After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 450722 - Multi-threaded crash in libgsf 1.4.4
Multi-threaded crash in libgsf 1.4.4
Status: RESOLVED DUPLICATE of bug 64764
Product: libgsf
Classification: Core
Component: General
1.14.x
Other All
: High critical
: ---
Assigned To: Jody Goldberg
Jody Goldberg
: 453264 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2007-06-24 19:49 UTC by Bogdan Nicula
Modified: 2007-07-15 02:43 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test program that crashes on my computer (530 bytes, text/plain)
2007-06-25 20:42 UTC, Bogdan Nicula
Details

Description Bogdan Nicula 2007-06-24 19:49:47 UTC
Steps to reproduce:
I'm getting crashes in a multithreaded application that works fine with version 1.4.3. Both glib and libgsf HEAD. Any idea?

Stack trace:
GLib-GObject-ERROR **: g_type_plugin_*(0x27fc1e0) invalidly modified type `GsfInfileZip'
aborting...

Thread 2:
0   libSystem.B.dylib   0x900248c7 semaphore_wait_signal_trap + 7
1   swb                 0x000e318b g_static_rw_lock_writer_lock + 190 (gthread.c:828)
2   swb                 0x000774d4 g_type_class_ref + 27 (gtype.c:318)
3   swb                 0x00077e56 g_type_create_instance + 171 (gtype.c:1451)
4   swb                 0x0013866d g_param_spec_internal + 204 (gparam.c:314)
5   swb                 0x0013a8f6 g_param_spec_int + 97 (gparamspecs.c:1587)
6   swb                 0x001189c2 gsf_infile_zip_class_init + 264 (gsf-infile-zip.c:829)
7   swb                 0x00077d01 g_type_class_ref + 2120 (gtype.c:1876)
8   swb                 0x00067c81 g_object_new_valist + 249 (gobject.c:990)
9   swb                 0x00067f09 g_object_new + 82 (gobject.c:799)
10  swb                 0x00118ae5 gsf_infile_zip_new + 158 (gsf-infile-zip.c:872)
...
16  libSystem.B.dylib   0x90024227 _pthread_body + 84

Thread 3 Crashed:
0   swb                 0x0012f78c g_logv + 1051 (gmessages.c:503)
1   swb                 0x0012f81e g_log + 41 (gmessages.c:519)
2   swb                 0x00077904 g_type_class_ref + 1099 (gtype.c:1075)
3   swb                 0x00067c81 g_object_new_valist + 249 (gobject.c:990)
4   swb                 0x00067f09 g_object_new + 82 (gobject.c:799)
5   swb                 0x00118ae5 gsf_infile_zip_new + 158 (gsf-infile-zip.c:872)



Other information:
Comment 1 Jody Goldberg 2007-06-25 01:31:39 UTC
Looks like two threads are trying to create a GsfInfileZip simultaneously, which should be just fine.  You've called gsf_init beforehand ?

Between 1.4.3 and 1.4.4 we moved to a new mechanism for registering the types, but it's been incubating for several months without incident.  I'm not sure what the error message means, and the gtype code at that level is somewhat opaque without further study.  I'll tack Tim Janik on the CC list, he's likely to have a more intuitive grasp of what you're seeing.

Any chance of a sample to replicate the problem ?
Comment 2 Bogdan Nicula 2007-06-25 20:06:52 UTC
Yes, gsf_init () is called at program startup.

What I find surprising that this code for registering the types is run for every libgsf object creation. Now I remember seeing this function, type_data_ref_Wm (), quite high in the profile and wondering about it.

I also get crashes with gsf_input_memory_new (), there's nothing special about `GsfInfileZip', I guess the problem is in the gobject library. I will try to come up with a sample.
Comment 3 Bogdan Nicula 2007-06-25 20:42:20 UTC
Created attachment 90635 [details]
Test program that crashes on my computer

Actually it's very easy to trigger, see attached.
It either crashes similarly with:

GLib-GObject-ERROR **: g_type_plugin_*(0x4fd0a0) invalidly modified type `GsfInputMemory'

or

GLib-GObject-ERROR **: file gtype.c: line 1776 (type_class_init_Wm): assertion failed: (node->is_classed && node->data && node->data->class.class_size && !node->data->class.class && node->data->class.init_state == UNINITIALIZED)

Maybe there are other ways, but I got bored :-)

My computer is an Intel Mac (OS 10.4), two core processor.
Comment 4 Jody Goldberg 2007-06-26 00:30:21 UTC
replicated on using sample code on a dual-athlon linux system.
Comment 5 Matthias Clasen 2007-06-26 02:11:55 UTC
The problem seems to be that type_data_ref_Wm drops the lock in the middle of the critical section to call g_type_plugin functions. If that is necessary, then it should not assert that node->data is still NULL when it enters the second critical section, but instead silently bail out/jump to the else branch of the outer if...
Comment 6 Bogdan Nicula 2007-06-26 11:21:32 UTC
Dunno if it's interesting for you: I made a stupid, un-scientific test (similar to the program above, but in a single thread) of creating and destroying libgsf objects. It confirmed my observation that it became slower since the new mechanism for registering types. About 3 times.

libgsf 1.4.3
29.7s with g_thread_init ()
15.7s without g_thread_init ()

libgsf HEAD
83.6s with g_thread_init ()
43.5s without g_thread_init ()

Comment 7 Jody Goldberg 2007-06-27 02:40:59 UTC
Your test is moderately interesting but something of a special case.  The slowdown is caused by the use of dynamic types that are clearing themselves when the last instance is unrefed.  For a test that creates then unrefs a type again and again we're going to see a slowdown.  We can easily work around it by keeping a ref to the class on registration.

However, that doesn't really impact the problem at hand which is that glib dynamic types are not threadsafe, and there is nothing we can do to fix that from within libgsf.  I'll going to back out the switch to dynamic types to avoid depending on a ultra new version of glib (whenever we get a fix).
Comment 8 Bogdan Nicula 2007-06-28 13:12:35 UTC
I retract my claim that this problem doesn't show up with libgsf 1.14.3. One just needs more patience and more runs to get the test program crash. For me it crashed several times at gtype.c:2389. I also verified with a simple GTK+ object as GtkAdjustment.

My conclusion is that the gobject type registration is not threadsafe and libgsf cannot do anything about it. Please close this bug, I will open another one against GLib.

In the meanwhile, after auditing my program for any gobject creation in threads, I worked around the bug by creating some relevant bogus objects at the program startup in the main thread. This has also the side effect of dropping g_object_new () way down in the time profile.

And, btw, thank you for this wonderful library!

Comment 9 Bogdan Nicula 2007-06-28 16:38:13 UTC
I now opened http://bugzilla.gnome.org/show_bug.cgi?id=451935.
Comment 10 Bogdan Nicula 2007-06-28 17:48:09 UTC
Apparently a long-standing issue.

*** This bug has been marked as a duplicate of 64764 ***
Comment 11 Jody Goldberg 2007-07-15 02:43:53 UTC
*** Bug 453264 has been marked as a duplicate of this bug. ***