Could use some help with variable length argument lists

Jeremy Faulkner gldisater at gldis.ca
Tue Feb 10 12:34:22 PST 2004


Bill Moran wrote:
> 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?
> 


va_start says that the last required variable is "message".

You can't use ap because it's not in the list of variables when you 
called the function.

_log(1, "Log test");
		  ^ There's nothing there to be "ap"

So it "Segmentation fault (core dumped)"'s

_log(1, "Log test", NULL);

-- 
Jeremy Faulkner				http://www.gldis.ca


More information about the freebsd-chat mailing list