<html>
<head>
<base href="http://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - Seemingly invalid code generation (segfault) with Boost Signals2"
href="http://llvm.org/bugs/show_bug.cgi?id=19096">19096</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Seemingly invalid code generation (segfault) with Boost Signals2
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>3.4
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>C++
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>tim@niemueller.de
</td>
</tr>
<tr>
<th>CC</th>
<td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=12206" name="attach_12206" title="Archive containing a demonstration program for the bug">attachment 12206</a> <a href="attachment.cgi?id=12206&action=edit" title="Archive containing a demonstration program for the bug">[details]</a></span>
Archive containing a demonstration program for the bug
clang seems to generate code which prematurely deletes a shared_ptr that is
actually still in use. The attached code segfaults on clang, but works just
fine on gcc.
The problem appears in a plugin scenario: a main program loads two plugins
(shared libraries via dlopen). One provides a Boost::Signals2 signal. The other
one connects a slot. Up to here everything works fine. -- Now we want to unload
the plugin containing the slot. We disconnect the slot from the signal, destroy
the handler, and unload the plugin. Afterwards, access to the signal slots
leads to a segfault. On GCC the code works just fine.
The Boost signal keeps a list of slot representatives around. If a slot is
disconnected, its representation is not immediately removed from the list, but
rather marked "disconnected". A new trigger to the signal would eventually
remove it. In our case, there is no signal call between disconnecting and the
segfault. Hence no cleanup happens. The representation is a shared_ptr to a
class instance which is created by the signal itself. It should not have been
freed at the time we call the "num_slots()" method. But dereferencing the
iterator segfaults. The same would happen when deleting the signal during the
call to disconnect_all_slots() method so it is not intrinsic to the particular
method.
Since this works just fine with GCC (simply replace CC=clang with CC=gcc in the
Makefile), I suspect it is a clang problem, rather than a Boost or custom code
problem. But I'd happily take hints should this still be the case.
I have attached an archive with some example code. It has the following files:
handler.{h,cpp}: compiled into shared library holding the slot
provider.{h,cpp}: compiled into shared library providing the signal
main.cpp: main program which dlopens both libs and invokes their
functionality
Once the program is built using make you can invoke it with
"./clang_boost_signals2_bug".
I have run into this problem on Fedora 20 with clang 3.3 and libstdc++ 4.8.2
and Boost 1.54.0. I have also tried on Fedora Rawhide with clang 3.4 (libstdc++
and Boost the same versions as F-20) and the problem persists.
The original problem occured as part of a plugin development for our robot
software framework Fawkes. The code has not been pushed to the public
repository, yet. But I can do this quickly should it be necessary. But the
attached example is a (strong) simplification of the problem and I get the
segfault in the same place (Boost).</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>