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 539186 - destroy() deletes its Glib::Source instance
destroy() deletes its Glib::Source instance
Status: RESOLVED DUPLICATE of bug 561885
Product: glibmm
Classification: Bindings
Component: main loop
2.16.x
Other Linux
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2008-06-19 21:03 UTC by Bryan Silverthorn
Modified: 2009-05-17 03:11 UTC
See Also:
GNOME target: ---
GNOME version: 2.21/2.22


Attachments
glibmm_source_destroy.cc (961 bytes, text/plain)
2008-06-19 21:06 UTC, Bryan Silverthorn
Details

Description Bryan Silverthorn 2008-06-19 21:03:56 UTC
In the glib C API, g_source_destroy() removes a source from its attached context and marks it as destroyed; that's also the behavior documented for Glib::Source::destroy(). The glibmm implementation, however, ends up deleting the Glib::Source instance, not merely marking it as destroyed.

The same instance is later deleted again by its Glib::RefPtr, so calling destroy() can easily and unavoidably cause heap corruption. This issue makes it effectively impossible to safely detach a source from a context in glibmm.

I've attached a small example involving a derived source. The same issue is also present for the standard event sources (Glib::TimeoutSource and friends).
Comment 1 Bryan Silverthorn 2008-06-19 21:06:22 UTC
Created attachment 113073 [details]
glibmm_source_destroy.cc

Test case.

Observed behavior:

"
$ ./glibmm_source_destroy 
> source->destroy()
~DerivedSource()
<
> source->destroy()

(process:19011): GLib-CRITICAL **: g_source_destroy: assertion `source != NULL' failed
<
*** glibc detected *** ./glibmm_source_destroy: corrupted double-linked list: 0x08ffe4d0 ***
======= Backtrace: =========
/lib/libc.so.6[0xa867e4]
/lib/libc.so.6[0xa88613]
/lib/libc.so.6(cfree+0x96)[0xa88846]
/lib/libglib-2.0.so.0(g_free+0x36)[0xc44356]
/usr/lib/libglibmm-2.4.so.1(_ZNK4Glib11MainContext11unreferenceEv+0x1d)[0x729cccd]
./glibmm_source_destroy(_ZN4Glib6RefPtrINS_11MainContextEED1Ev+0x1c)[0x8048e3a]
./glibmm_source_destroy(__gxx_personality_v0+0x23c)[0x8048bb8]
/lib/libc.so.6(__libc_start_main+0xe6)[0xa2f5d6]
./glibmm_source_destroy(__gxx_personality_v0+0x55)[0x80489d1]
======= Memory map: ========
00110000-00111000 r-xp 00110000 00:00 0          [vdso]
0094c000-00959000 r-xp 00000000 fd:00 3999374    /lib/libgcc_s-4.3.0-20080428.so.1
00959000-0095a000 rw-p 0000c000 fd:00 3999374    /lib/libgcc_s-4.3.0-20080428.so.1
009f5000-00a11000 r-xp 00000000 fd:00 3997816    /lib/ld-2.8.so
00a11000-00a12000 r--p 0001c000 fd:00 3997816    /lib/ld-2.8.so
00a12000-00a13000 rw-p 0001d000 fd:00 3997816    /lib/ld-2.8.so
00a19000-00b7c000 r-xp 00000000 fd:00 3997867    /lib/libc-2.8.so
00b7c000-00b7e000 r--p 00163000 fd:00 3997867    /lib/libc-2.8.so
00b7e000-00b7f000 rw-p 00165000 fd:00 3997867    /lib/libc-2.8.so
00b7f000-00b82000 rw-p 00b7f000 00:00 0 
00b84000-00bab000 r-xp 00000000 fd:00 3999022    /lib/libm-2.8.so
00bab000-00bac000 r--p 00026000 fd:00 3999022    /lib/libm-2.8.so
00bac000-00bad000 rw-p 00027000 fd:00 3999022    /lib/libm-2.8.so
00baf000-00bb2000 r-xp 00000000 fd:00 3997898    /lib/libdl-2.8.so
00bb2000-00bb3000 r--p 00002000 fd:00 3997898    /lib/libdl-2.8.so
00bb3000-00bb4000 rw-p 00003000 fd:00 3997898    /lib/libdl-2.8.so
00bd1000-00beb000 r-xp 00000000 fd:00 3999377    /lib/libselinux.so.1
00beb000-00bec000 r--p 00019000 fd:00 3999377    /lib/libselinux.so.1
00bec000-00bed000 rw-p 0001a000 fd:00 3999377    /lib/libselinux.so.1
00c05000-00ce5000 r-xp 00000000 fd:00 3999384    /lib/libglib-2.0.so.0.1600.3
00ce5000-00ce6000 rw-p 000e0000 fd:00 3999384    /lib/libglib-2.0.so.0.1600.3
00cf4000-00d33000 r-xp 00000000 fd:00 3999388    /lib/libgobject-2.0.so.0.1600.3
00d33000-00d34000 rw-p 0003f000 fd:00 3999388    /lib/libgobject-2.0.so.0.1600.3
00d65000-00d68000 r-xp 00000000 fd:00 3999389    /lib/libgmodule-2.0.so.0.1600.3
00d68000-00d69000 rw-p 00002000 fd:00 3999389    /lib/libgmodule-2.0.so.0.1600.3
02031000-02036000 r-xp 00000000 fd:00 12044441   /usr/lib/libsigc-2.0.so.0.0.0
02036000-02037000 rw-p 00004000 fd:00 12044441   /usr/lib/libsigc-2.0.so.0.0.0
02ad9000-02bc0000 r-xp 00000000 fd:00 12032670   /usr/lib/libstdc++.so.6.0.10
02bc0000-02bc4000 r--p 000e6000 fd:00 12032670   /usr/lib/libstdc++.so.6.0.10
02bc4000-02bc6000 rw-p 000ea000 fd:00 12032670   /usr/lib/libstdc++.so.6.0.10
02bc6000-02bcb000 rw-p 02bc6000 00:00 0 
07269000-072bc000 r-xp 00000000 fd:00 12043870   /usr/lib/libglibmm-2.4.so.1.0.24
072bc000-072be000 rw-p 00053000 fd:00 12043870   /usr/lib/libglibmm-2.4.so.1.0.24
08048000-0804a000 r-xp 00000000 fd:00 17958628   /home/bsilvert/arlut/home/bsilvert/toyprograms/glibmm_source_destroy/glibmm_source_destroy
0804a000-0804b000 rw-p 00001000 fd:00 17958628   /home/bsilvert/arlut/home/bsilvert/toyprograms/glibmm_source_destroy/glibmm_source_destroy
08ffe000-0901f000 rw-p 08ffe000 00:00 0          [heap]
b7f00000-b7f21000 rw-p b7f00000 00:00 0 
b7f21000-b8000000 ---p b7f21000 00:00 0 
b8088000-b808b000 rw-p b8088000 00:00 0 
b8098000-b809f000 r--s 00000000 fd:00 12128132   /usr/lib/gconv/gconv-modules.cache
b809f000-b80a1000 rw-p b809f000 00:00 0 
bfd8c000-bfda1000 rw-p bffeb000 00:00 0          [stack]
Aborted
"
Comment 2 Murray Cumming 2008-06-22 11:38:50 UTC
A destroy function on a ref-counted instance is very odd. I can't see how we could make that make sense for C++ or most other higher-level language bindings.

Is there no other way to explicitly "detach" it? I guess there should be. 
Comment 3 Bryan Silverthorn 2008-06-23 17:35:58 UTC
The g_source_destroy() function is a bit weird, and its name is misleading. It doesn't actually delete the instance per se; it detaches the source from its context and moves it into a "destroyed" state (in which it is an error to call _almost_ all of its methods, but not, eg, g_source_is_destroyed()). The refcount is still responsible for eventually deleting the instance.

As far as I'm aware, there's no other way to remove a source from its context, but I'm not sure that there should be---destroy() has, more or less, the semantics you would want in an explicit "detach()" method.
Comment 4 Jonathon Jongsma 2009-05-17 03:11:08 UTC
Well, this bug was filed first, but I didn't notice it and there is more discussion on Bug 561885, so I'm going to close this one as a dup.

*** This bug has been marked as a duplicate of 561885 ***