Bug#591075: glib2.0 segv
Ulrich Weigand
uweigand at de.ibm.com
Fri Aug 6 13:37:30 UTC 2010
Alexander Sack asked me to look into this.
I can reproduce the problem on Ubuntu maverick, and I fact I get this
compile-time warning that already indicates the problem:
In function 'memset',
inlined from 'g_bsearch_array_create' at /home/uweigand/linaro/glib2.0-2.25.12/glib/gbsearcharray.h:137,
inlined from 'g_signal_init' at /home/uweigand/linaro/glib2.0-2.25.12/gobject/gsignal.c:775:
//usr/include/bits/string3.h:86: warning: call to __builtin___memset_chk will always overflow destination buffer
What's going on here is that everything is inlined into g_signal_init,
and the whole computation of "size" can be done at compile time. This means:
size = sizeof (GBSearchArray) + bconfig->sizeof_node;
if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)
size = G_BSEARCH_UPPER_POWER2 (size);
gets simplified to
size = sizeof (GBSearchArray) + sizeof (SignalKey);
size = G_BSEARCH_UPPER_POWER2 (size);
which becomes
size = sizeof (GBSearchArray) + sizeof (SignalKey);
size = 1 << g_bit_storage (size - 1);
which in turn is
size = sizeof (GBSearchArray) + sizeof (SignalKey);
size = 1 << (((GLIB_SIZEOF_LONG * 8 - 1) ^ __builtin_clzl (size - 1)) + 1);
Now the problem is that GLIB_SIZEOF_LONG is defined to 8,
even though this is a 32-bit build and sizeof (unsigned long) is 4.
This causes the shift size to be some value greater than 32,
and the result of the shift to be undefined, which happens to
be optimized to 0.
The reason for the wrong GLIB_SIZEOF_LONG seems to be a build issue.
The value is picked up from a file glib2.0-2.25.12/glib/glibconfig.h
which appears to have been generated on a 64-bit machine.
There is also another, apparently correct, version in
glib2.0-2.25.12/debian/build/deb/glib/glibconfig.h
but due to include path ordering, the one in glib/ gets picked up.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand at de.ibm.com
More information about the pkg-gnome-maintainers
mailing list