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 127928 - Bug related to SigC::Connection::disconnect()
Bug related to SigC::Connection::disconnect()
Status: RESOLVED FIXED
Product: libsigc++
Classification: Bindings
Component: signals
1.2
Other All
: High critical
: ---
Assigned To: Martin Schulze
Martin Schulze
Depends on:
Blocks:
 
 
Reported: 2003-11-25 22:01 UTC by Ole André Vadla Ravnås
Modified: 2005-01-28 23:04 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Attaching test-case (2.08 KB, text/plain)
2003-11-25 22:07 UTC, Ole André Vadla Ravnås
  Details
signal_cleanup_fix.diff (1.66 KB, patch)
2003-11-30 16:36 UTC, Martin Schulze
none Details | Review
Patch to fix bug 127928 in libsigc++ 1.2.5. (2.01 KB, patch)
2004-08-12 10:10 UTC, Andrew Bettison
none Details | Review
Better patch for 1.2.5 (3.33 KB, patch)
2004-08-12 11:25 UTC, Andrew Bettison
none Details | Review
libsigc_1p2_remove.patch (4.83 KB, patch)
2005-01-28 23:04 UTC, Murray Cumming
none Details | Review

Description Ole André Vadla Ravnås 2003-11-25 22:01:01 UTC
There is a bug related to SigC::Connection::disconnect() when changing
connections from within a signal handler, more specifically disconnect()ing
a slot from a signal and connecting another one. This results in attempts
to access data that has been free()'d/deleted when the signal is emitted,
leading to random results, from no visible effect at all to crashes.
Comment 1 Ole André Vadla Ravnås 2003-11-25 22:06:26 UTC
Output when the test-case is run through valgrind:

==17803== Memcheck, a.k.a. Valgrind, a memory error detector for
x86-linux.
==17803== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==17803== Using valgrind-2.0.0, a program supervision framework for
x86-linux.
==17803== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==17803== Estimated CPU clock rate is 2842 MHz
==17803== For more details, rerun with: -v
==17803== 
connected
send_cmd: sending 'hello'
mainloop: about to emit recv_message signal
recv_line: arbitrary reply
handle_reply_a: arbitrary reply
send_cmd: sending 'user'
handle_reply_b: arbitrary reply
send_cmd: sending 'pass'
handle_reply_c: arbitrary reply
mainloop: done emitting recv_message signal
==17803== Invalid read of size 4
==17803==    at 0x40252062: SigC::SignalNode::clear() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025200B: SigC::SignalNode::~SignalNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x402523AF: SigC::SignalBase::~SignalBase() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x804A1B4: SigC::Signal1<void, std::string,
SigC::Marshal<void> >::~Signal1() (in /home/zole/testapp/a.out)
==17803==    Address 0x413995D0 is 4 bytes inside a block of size 36
free'd
==17803==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40252556:
SigC::SignalConnectionNode::~SignalConnectionNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025215E: SigC::SignalNode::cleanup() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803== 
==17803== Invalid read of size 4
==17803==    at 0x40252065: SigC::SignalNode::clear() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025200B: SigC::SignalNode::~SignalNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x402523AF: SigC::SignalBase::~SignalBase() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x804A1B4: SigC::Signal1<void, std::string,
SigC::Marshal<void> >::~Signal1() (in /home/zole/testapp/a.out)
==17803==    Address 0x413995E8 is 28 bytes inside a block of size 36
free'd
==17803==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40252556:
SigC::SignalConnectionNode::~SignalConnectionNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025215E: SigC::SignalNode::cleanup() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803== 
==17803== Invalid write of size 4
==17803==    at 0x40252068: SigC::SignalNode::clear() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025200B: SigC::SignalNode::~SignalNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x402523AF: SigC::SignalBase::~SignalBase() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x804A1B4: SigC::Signal1<void, std::string,
SigC::Marshal<void> >::~Signal1() (in /home/zole/testapp/a.out)
==17803==    Address 0x413995E4 is 24 bytes inside a block of size 36
free'd
==17803==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40252556:
SigC::SignalConnectionNode::~SignalConnectionNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025215E: SigC::SignalNode::cleanup() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803== 
==17803== Invalid write of size 4
==17803==    at 0x40252074: SigC::SignalNode::clear() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025200B: SigC::SignalNode::~SignalNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x402523AF: SigC::SignalBase::~SignalBase() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x804A1B4: SigC::Signal1<void, std::string,
SigC::Marshal<void> >::~Signal1() (in /home/zole/testapp/a.out)
==17803==    Address 0x413995D0 is 4 bytes inside a block of size 36
free'd
==17803==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==17803==    by 0x40252556:
SigC::SignalConnectionNode::~SignalConnectionNode() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803==    by 0x4025215E: SigC::SignalNode::cleanup() (in
/usr/lib/libsigc-1.2.so.5.0.5)
==17803== 
==17803== ERROR SUMMARY: 8 errors from 4 contexts (suppressed: 0 from 0)
==17803== malloc/free: in use at exit: 960 bytes in 1 blocks.
==17803== malloc/free: 12 allocs, 11 frees, 1306 bytes allocated.
==17803== For a detailed leak analysis,  rerun with: --leak-check=yes
==17803== For counts of detected errors, rerun with: -v
Comment 2 Ole André Vadla Ravnås 2003-11-25 22:07:59 UTC
Created attachment 21811 [details]
Attaching test-case
Comment 3 Martin Schulze 2003-11-30 16:35:43 UTC
I can't reproduce the bug because there is no FreeBSD port of valgrind
:( However I had a guess at the bug. Please try the attached patch
against lisigc++-1.2 cvs or the libsigc++-1.2.5 tarball and check if
the problem is gone.
Comment 4 Martin Schulze 2003-11-30 16:36:56 UTC
Created attachment 21942 [details] [review]
signal_cleanup_fix.diff
Comment 5 Ole André Vadla Ravnås 2003-11-30 22:43:51 UTC
Ok, thanks. I tried your patch but there are still problems, although
they have changed slightly:

==9790== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
==9790== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==9790== Using valgrind-2.0.0, a program supervision framework for
x86-linux.
==9790== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==9790== Estimated CPU clock rate is 2850 MHz
==9790== For more details, rerun with: -v
==9790== 
connected
send_cmd: sending 'hello'
mainloop: about to emit recv_message signal
recv_line: arbitrary reply
handle_reply_a: arbitrary reply
send_cmd: sending 'user'
handle_reply_b: arbitrary reply
send_cmd: sending 'pass'
handle_reply_c: arbitrary reply
==9790== Invalid write of size 4
==9790==    at 0x4024691B: SigC::SignalNode::cleanup() (signal.cc:123)
==9790==    by 0x804A463: SigC::SignalNode::exec_unreference() (in
/home/zole/testapp/a.out)
==9790==    by 0x804A2A4: SigC::SignalExec_::~SignalExec_() (in
/home/zole/testapp/a.out)
==9790==    by 0x804A1E6: SigC::Signal1<void, std::string,
SigC::Marshal<void> >::emit_(std::string const&, void*) (in
/home/zole/testapp/a.out)
==9790==    Address 0x4139A5E8 is 28 bytes inside a block of size 36
free'd
==9790==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40246EA7:
SigC::SignalConnectionNode::~SignalConnectionNode() (signal.cc:236)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
mainloop: done emitting recv_message signal
==9790== 
==9790== Invalid read of size 4
==9790==    at 0x40246835: SigC::SignalNode::clear() (signal.cc:51)
==9790==    by 0x402467A7: SigC::SignalNode::~SignalNode() (signal.cc:41)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790==    by 0x40246C88: SigC::SignalBase::~SignalBase() (signal.cc:214)
==9790==    Address 0x4139A5E8 is 28 bytes inside a block of size 36
free'd
==9790==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40246EA7:
SigC::SignalConnectionNode::~SignalConnectionNode() (signal.cc:236)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790== 
==9790== Invalid write of size 4
==9790==    at 0x4024683E: SigC::SignalNode::clear() (signal.cc:52)
==9790==    by 0x402467A7: SigC::SignalNode::~SignalNode() (signal.cc:41)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790==    by 0x40246C88: SigC::SignalBase::~SignalBase() (signal.cc:214)
==9790==    Address 0x4139A5E4 is 24 bytes inside a block of size 36
free'd
==9790==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40246EA7:
SigC::SignalConnectionNode::~SignalConnectionNode() (signal.cc:236)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790== 
==9790== Invalid read of size 4
==9790==    at 0x804A48D: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790==    by 0x4024684F: SigC::SignalNode::clear() (signal.cc:53)
==9790==    by 0x402467A7: SigC::SignalNode::~SignalNode() (signal.cc:41)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790==    Address 0x4139A5D0 is 4 bytes inside a block of size 36 free'd
==9790==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40246EA7:
SigC::SignalConnectionNode::~SignalConnectionNode() (signal.cc:236)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790== 
==9790== Invalid read of size 4
==9790==    at 0x804A490: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790==    by 0x4024684F: SigC::SignalNode::clear() (signal.cc:53)
==9790==    by 0x402467A7: SigC::SignalNode::~SignalNode() (signal.cc:41)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790==    Address 0x4139A5D0 is 4 bytes inside a block of size 36 free'd
==9790==    at 0x40028DED: __builtin_delete (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40028E18: operator delete(void*) (in
/usr/lib/valgrind/vgskin_memcheck.so)
==9790==    by 0x40246EA7:
SigC::SignalConnectionNode::~SignalConnectionNode() (signal.cc:236)
==9790==    by 0x804A4AD: SigC::NodeBase::unreference() (in
/home/zole/testapp/a.out)
==9790== 
==9790== ERROR SUMMARY: 7 errors from 5 contexts (suppressed: 0 from 0)
==9790== malloc/free: in use at exit: 960 bytes in 1 blocks.
==9790== malloc/free: 12 allocs, 11 frees, 1306 bytes allocated.
==9790== For a detailed leak analysis,  rerun with: --leak-check=yes
==9790== For counts of detected errors, rerun with: -v
Comment 6 Martin Schulze 2003-12-01 00:26:25 UTC
Hm, I will try ElectricFence tomorrow. Maybe it also reports some of
these errors. It's hard to debug if you don't know where to look ...
Do the errors also show up if you omit the recv_line, the
handle_reply_a and / or the handle_reply_b slots? I think it would
help to further simplify the test case based on this information.
Comment 7 Martin Schulze 2003-12-03 23:06:18 UTC
ElectricFence doesn't seem to trigger any errors. I will try valgrind
at work. This will have to wait a few days, however, because I'm
currently working with a "Knoppix-PC" without hard disk ...
Comment 8 Murray Cumming 2004-07-17 13:25:51 UTC
If this happens only in gtkmm rather than a pure libsigc++ program, then you
might like to know that I fixed this in glibmm recently.

Calling valgrind with --num-callers=20 often gives more context.
Comment 9 Andrew Bettison 2004-08-12 10:10:10 UTC
Created attachment 30462 [details] [review]
Patch to fix bug 127928 in libsigc++ 1.2.5.

Try this patch... it fixes the test case completely on my system.
Comment 10 Andrew Bettison 2004-08-12 11:25:45 UTC
Created attachment 30468 [details] [review]
Better patch for 1.2.5

This one is even better.
Comment 11 Murray Cumming 2004-09-19 14:13:08 UTC
Martin, does this look OK?
Comment 12 Martin Schulze 2004-09-26 16:10:01 UTC
I don't really know the background of the code in the affected routine. I
remember that there already were patches from different people to this.
So me too, I can only guess that the patch is okay if all test cases are still
working...
Comment 13 Murray Cumming 2004-10-07 07:34:02 UTC
I would prefer to see a version of this patch that did not include irrelevant
changes, such as additions of whitespace and consts, but Martin might not care
about that as much as me. If so, this should probably be committed if the tests
cases still work with it.
Comment 14 Murray Cumming 2005-01-28 23:03:31 UTC
I have applied this patch. The change seems simple and good.
Comment 15 Murray Cumming 2005-01-28 23:04:25 UTC
Created attachment 36674 [details] [review]
libsigc_1p2_remove.patch