vprintf segfault on Ubuntu Linux 15.10

I have a C program with a ‘print’ function that accepts a format string and variable list of arguments, similar to printf style functions. The function simply prints to stdout and also to a logfile.

void print(const char* format, ...) {
	pthread_mutex_lock(&logfile_mutex);
 
	va_list args;
	va_start(args,format);
 
	vprintf(format,args);
	fflush(stdout);
 
	fprintf(logfile,"%d ",milli_timer());
	vfprintf(logfile,format,args);
	fflush(logfile);
 
	va_end(args);
 
	pthread_mutex_unlock(&logfile_mutex);
}

Everything seemed fine compiling with g++ under Cygwin, but would crash when compiled on Ubuntu Linux 15.10. After a bit of digging I finally spotted the problem in the documentation for vprintf:

Internally, the function retrieves arguments from the list identified by arg as if va_arg was used on it, and thus the state of arg is likely altered by the call.

Apparently this is one of those things that is compiler specific. Since we can’t rely on the state of the arguments list after the first call to vprintf, the solution was simply to use a new arguments list for the second call to vprintf which writes to the log file. Revised function:

void print(const char* format, ...) {
	pthread_mutex_lock(&logfile_mutex);
 
	va_list stdout_args;
	va_start(stdout_args,format);
	vprintf(format,stdout_args);
	fflush(stdout);
	va_end(stdout_args);
 
	va_list log_args;
	va_start(log_args,format);
	fprintf(logfile,"%d ",milli_timer());
	vfprintf(logfile,format,log_args);
	fflush(logfile);
	va_end(log_args);
 
	pthread_mutex_unlock(&logfile_mutex);
}

Hope that helps someone.

This entry was posted in Software Development. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *