'How to avoid non-copyable characters in a C application, run by Eclipse

I am working with a C application, which is tested by a Java application, run in Eclipse. The Java application runs the C application, using the standard way:

Runtime.getRuntime().exec(cmdline)

(the cmdline containing the C application's executable)

The C application most probably uses Visual Studio's vsprintf() function for writing something, but in some cases, a non-copyable character seems to be printed, as you can see:

put_log(LOG_INFO, "Waiting for writing thread\n");

(put_log() is most probably based on the mentioned vsprintf())
ps -ef This gets shown in Eclipse as:

INFO : aiting for writing thread

As you see, the "W" has disappeared, and in top of that, when I try to copy the mentioned line, I only see:

INFO : 

I have the impression that the letter W has been replaced by a character, which is not copyable to the Windows clipboard. As this happens in the middle of quite a large output, this is very annoying.

Does anybody understand what is going on and how I can solve this?

As asked by Fluter, hereby an excerpt of the put_log() function:

void put_log(const char *fmt, ...)
{
  static char str[16384];
  char* args;
  char* p = str;

  strcpy(str, "INFO: ");

  p = str + strlen(str);

  _crt_va_start(args, fmt);
  vsprintf(p, fmt, args);
  _crt_va_end(args);
  ...
}

(the first argument(LOG_INFO) is removed from this excerpt and replaced by the "INFO: " hardcoded string for simplification purposes)

For your information, hereby the location of the lowlevel functions:

  • _crt_va_start() : c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\stdarg.h
  • _crt_va_end() : c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\stdarg.h
  • vsprintf() : C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src\vsprintf.c

Thanks



Solution 1:[1]

You didn't post how is the log actually get printed on the console, make sure you print it with right functions, for example fprintf(stderr, str);

Second, you are using a static buffer here, it is subject to in data race when the function is called concurrently, possibly by multiple threads. Obviously the buffer is overwritten for every log, it does not make sense to use static here, yet brings the problem of corrupted data.

void put_log(const char *fmt, ...)
{
    char str[16384];
    char* args;
    char* p = str;
    va_list list;

    strcpy(str, "INFO: ");

    p = str + strlen(str);

    va_start(list, fmt);
    vsprintf(p, fmt, list);
    va_end(list);

    fprintf(stderr, str);
}

Solution 2:[2]

Assuming _crt_va_start behaves like standard C va_start, then you need to declare a va_list somewhere, rather than using some uninitialized char pointer. Reason why it seems to work is probably because va lists have non-existent type safety (and therefore using them to begin with is bad practice).

Do something like this instead:

#include <stdarg.h>

void put_log(const char *fmt, ...)
{
  static char str[16384];
  va_list va;
  char* p = str;

  strcpy(str, "INFO: ");
  p = str + strlen(str);

  va_start(va, fmt);
  vsprintf(p, fmt, va);
  va_end(va);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Lundin