Could use some help with variable length argument lists

Bill Moran wmoran at potentialtech.com
Tue Feb 10 12:12:45 PST 2004


I'm so frustrated I could cry.

I want my application to be able to do all kinds of logging, so I wrote a log
function:

void
_log(int level, const char *message, ...)
{
     va_list ap;
     char **format, **errmsg;

     va_start(ap, message);
     if (level <= LOGLEVEL) {
         asprintf(format, "PID %d: %s", getpid(), message);
         vasprintf(errmsg, *format, ap);
         free(*format);
         syslog(LOG_INFO | LOG_LOCAL1, *errmsg);
         if (LOGLEVEL == 10)
             printf(*errmsg);
         free(*errmsg);
     }
     va_end(ap);
}

Doesn't seem too difficult, right?  However, if I call the function
from elsewhere in my application like this:

_log(1, "Log test");

I get a coredump!  gdb complains that message is "out of bounds"
on the line "asprintf(format, "PID %d: %s", getpid(), message);"

I'm at the end of my rope with this.  I really need a way to easily
log with variable arguments or I'll never get some other issues with
this application debugged!  If I tweak the _log function to this:

void
_log(int level, char *message)
{
     if (level <= LOGLEVEL) {
         syslog(LOG_INFO | LOG_LOCAL1, "PID %d: %s", getpid(), message);
         if (LOGLEVEL == 10)
             printf("PID %d: %s", getpid(), message);
     }
}

everything works just dandy (I haven't changed any other code anywhere
else!  I'm not _using_ variable arguments to _log() yet)

What is is between these two functions that causes the first one to
coredump, yet the second one works fine?  I can only guess that my
usage of va_* isn't quite right, but how is that affecting the message
pointer?

-- 
Bill Moran
Potential Technologies
http://www.potentialtech.com



More information about the freebsd-chat mailing list