GNOME Bugzilla – Bug 743466
core dump in wrap_register() when calling deprecated Glib::thread_init()
Last modified: 2016-04-10 15:24:24 UTC
This small test program leads to a crash and core dump in Glib::wrap_register() when using the latest glibmm 2.43.3 on Fedora Rawhide (22). This test replicates how GParted (threaded gtkmm 2.x GUI app) is coded and crashes. Bug reports for this: Debian #765283 - gparted crashing during scan https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765283 RedHat #1178302 - [abrt] gparted: Glib::wrap_register(): gpartedbin killed by SIGSEGV https://bugzilla.redhat.com/show_bug.cgi?id=1178302 GNOME Bug 743399 - GParted 0.19.0-2 segfaults with error in Glib::wrap_register() https://bugzilla.gnome.org/show_bug.cgi?id=743399 /* gcc -g -o test test.cc `pkg-config gtkmm-2.4 --cflags --libs` */ #include <stdlib.h> #include <gtkmm/main.h> int main(int argc, char *argv[]) { Glib::thread_init(); return EXIT_SUCCESS; } $ gdb test GNU gdb (GDB) Fedora 7.8.50.20150108-1.fc22 Reading symbols from test...done. (gdb) run Starting program: /home/fedora/programming/c/test [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007ffff6476c8a in Glib::wrap_register(unsigned long, Glib::ObjectBase* (*)(_GObject*)) () from /lib64/libglibmm-2.4.so.1 (gdb) backtrace
+ Trace 234583
It's crashing here in wrap_register() on line 88 because wrap_func_table is a NULL pointer and hasn't been initialised yet. wrap_register_init() hasn't been called yet. file: glibmm/glib/glibmm/wrap.cc 80 void wrap_register(GType type, WrapNewFunction func) 81 { 82 //0 is not a valid GType. 83 //It would lead to a critical warning in g_type_set_qdata(). 84 //We allow this, failing silently, to make life easier for ... 85 if(type == 0) 86 return; 87 >>> 88 const guint idx = wrap_func_table->size(); 89 wrap_func_table->push_back(func); 90 91 // Store the table index in the type's static data. 92 g_type_set_qdata(type, Glib::quark_, GUINT_TO_POINTER(idx)); 93 } Call chain: Glib::thread_init() Glib::thread_init_impl() Glib::Error::register_init() Glib::wrap_init() Glib::wrap_register() Suspect that this patch made the difference is as it changed Glib::wrap_init() to call Glib::wrap_register() for the first time. https://git.gnome.org/browse/glibmm/commit/?id=983dd287da4b00baedbd04ce0f777c043d93f5b0
Here's a complete backtrace without function calls optimised away. (gdb) backtrace
+ Trace 234584
Created attachment 295362 [details] [review] Prevent core dump when calling deprecated Glib::thread_init() (v1) Here's a fix for this. Note that this makes thread_init_impl(), and therefore Glib::thread_init(), identical to calling Glib::init(). I.E. they both do: Glib::wrap_register_init(); Glib::Error::register_init(); Thanks, Mike
I have pushed the patch https://git.gnome.org/browse/glibmm/commit/?id=10e24926a149c8dbfbc5853b2d4ff5a4cd50bc4b I fixed the bug by calling Glib::wrap_register_init() from Glib::Error::register_init() before calling Glib::wrap_init(). That's the only call to Glib::wrap_init() in glibmm. Thanks for the unusually detailed description of the bug. I could argue that it's an error to call any glibmm function before calling Glib::init(), but since previously working programs crash after I added Glib::Binding, I prefer to make glibmm at least as robust as it was before.
*** Bug 743399 has been marked as a duplicate of this bug. ***