Fix varargs use

"man stdarg" says:
  If ap is passed to a function that uses va_arg(ap,type) then the value
  of ap is undefined after the return of that function.

va_start(…) and va_end(…) must be called at each iteration.

By chance, it worked in 32 bits, but it segfaulted in 64 bits.

See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31484
This commit is contained in:
Romain Vimont (®om) 2013-05-29 23:44:31 +02:00
parent 43af757262
commit f88dff08a6

38
log.c
View File

@ -389,37 +389,30 @@ static int _log_iterator_next(_log_iterator *it, int level)
return 0; return 0;
} }
static void _log_iterator_vprintf_nl(_log_iterator *it, int level, struct __sourceloc whence, const char *fmt, va_list ap)
{
_log_iterator_rewind(it);
while (_log_iterator_next(it, level)) {
_log_prefix_whence(it, whence);
vxprintf(it->xpf, fmt, ap);
}
}
static void _log_iterator_printf_nl(_log_iterator *it, int level, struct __sourceloc whence, const char *fmt, ...) static void _log_iterator_printf_nl(_log_iterator *it, int level, struct __sourceloc whence, const char *fmt, ...)
{ {
va_list ap; va_list ap;
_log_iterator_rewind(it);
while (_log_iterator_next(it, level)) {
_log_prefix_whence(it, whence);
va_start(ap, fmt); va_start(ap, fmt);
_log_iterator_vprintf_nl(it, level, whence, fmt, ap); vxprintf(it->xpf, fmt, ap);
va_end(ap); va_end(ap);
} }
static void _logs_vprintf_nl(int level, struct __sourceloc whence, const char *fmt, va_list ap)
{
_log_iterator it;
_log_iterator_start(&it);
_log_iterator_vprintf_nl(&it, level, whence, fmt, ap);
} }
static void _logs_printf_nl(int level, struct __sourceloc whence, const char *fmt, ...) static void _logs_printf_nl(int level, struct __sourceloc whence, const char *fmt, ...)
{ {
va_list ap; va_list ap;
_log_iterator it;
_log_iterator_start(&it);
while (_log_iterator_next(&it, level)) {
_log_prefix_whence(&it, whence);
va_start(ap, fmt); va_start(ap, fmt);
_logs_vprintf_nl(level, whence, fmt, ap); vxprintf(it.xpf, fmt, ap);
va_end(ap); va_end(ap);
} }
}
const char *log_file_directory_path() const char *log_file_directory_path()
{ {
@ -681,23 +674,16 @@ void logString(int level, struct __sourceloc whence, const char *str)
void logMessage(int level, struct __sourceloc whence, const char *fmt, ...) void logMessage(int level, struct __sourceloc whence, const char *fmt, ...)
{ {
if (level != LOG_LEVEL_SILENT) {
va_list ap; va_list ap;
va_start(ap, fmt);
vlogMessage(level, whence, fmt, ap);
va_end(ap);
}
}
void vlogMessage(int level, struct __sourceloc whence, const char *fmt, va_list ap)
{
if (level != LOG_LEVEL_SILENT) { if (level != LOG_LEVEL_SILENT) {
_log_iterator it; _log_iterator it;
_log_iterator_start(&it); _log_iterator_start(&it);
_rotate_log_file(&it); _rotate_log_file(&it);
while (_log_iterator_next(&it, level)) { while (_log_iterator_next(&it, level)) {
_log_prefix_whence(&it, whence); _log_prefix_whence(&it, whence);
va_start(ap, fmt);
vxprintf(it.xpf, fmt, ap); vxprintf(it.xpf, fmt, ap);
va_end(ap);
} }
} }
} }