GNOME Bugzilla – Bug 577137
g_logv() will crash if given format args and multiple log levels
Last modified: 2009-03-29 19:12:14 UTC
On NetBSD/macppc, if you call g_log() with multiple log levels *and* with a log message format string that has arguments (%s or whatever), it will crash. It looks like the problem is that g_logv() will use its va_list more than once without calling va_copy(). On many ppc systems this fails because va_list is defined as struct { stuff... } va_list[1]; meaning that it is, in effect, passed by reference in cases where an i386's simple pointer-to-the-stack va_list would be passed by value. As a result, the second invocation of *vprintf() picks up where the previous one left off, instead of starting at the beginning. Using va_copy() will portably make an independent copy of the va_list state, though. On the other hand, it doesn't look like g_logv() actually *needs* to traverse the argument list more than once: instead of calling *vprintf() for each log level, it could call it just once and use the resulting string for each log message. Here's a short program demonstrating the crash. Notice how it prints the message from the first of the multiple log levels, but fails trying to format it again for the next log level. $ cat ./valog2.c #include <glib.h> int main() { int foo1 = 42; char *foo2 = "fortytwo"; char *foo3 = "blah"; g_log("wargha", G_LOG_LEVEL_INFO, "A message at only one log level (%d %s %s)", foo1, foo2, foo3); g_log("wargha", G_LOG_LEVEL_INFO|G_LOG_LEVEL_MESSAGE, "A message at multiple log levels (%d %s %s)", foo1, foo2, foo3); } $ cc valog2.c `/usr/pkg/bin/pkg-config glib-2.0 --cflags --libs` $ ./a.out wargha-INFO: A message at only one log level (42 fortytwo blah) wargha-INFO: A message at multiple log levels (42 fortytwo blah) [2] Segmentation fault (core dumped) ./a.out $ gdb ./a.out GNU gdb 6.5 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "powerpc--netbsd"...(no debugging symbols found) (gdb) run Starting program: /home/wiml/bad_glib/a.out wargha-INFO: A message at only one log level (42 fortytwo blah) wargha-INFO: A message at multiple log levels (42 fortytwo blah) Program received signal SIGSEGV, Segmentation fault. 0xefea53a8 in strlen () from /usr/lib/libc.so.12 (gdb) bt
+ Trace 213949
On Debian this happens on s930 and powerpc when trying to run the tests that come with the perl Glib. The other architectures worked fine. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=520484
2009-03-29 Matthias Clasen <mclasen@redhat.com> Bug 577137 – g_logv() will crash if given format args and multiple log levels * glib/gmessages.c (g_logv): Copy a va_list when using it multiple times. Reported by Wim Lewis.