Boost C++ Libraries: Ticket #3926: thread_specific_ptr + dlopen library causes a SIGSEGV. https://svn.boost.org/trac10/ticket/3926 <p> hi, </p> <p> i've discovered that using thread_specific_ptr in shared library dlopened from thread causes a gpf.<br /> please consider following scenario: <br /><br /> spawn thread<br /> dlopen a shared library with thread_specific_ptr<br /> dlclose the library<br /> terminate the thread<br /> <br /> observe the gpf<br /> <br /> </p> <pre class="wiki">Program received signal SIGSEGV, Segmentation fault. 0x00007ffff62b7400 in ?? () (gdb) bt #0 0x00007ffff62b7400 in ?? () #1 0x00007ffff7221f79 in __nptl_deallocate_tsd () at pthread_create.c:154 #2 0x00007ffff722291b in start_thread (arg=&lt;value optimized out&gt;) at pthread_create.c:304 #3 0x00007ffff6f9293d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #4 0x0000000000000000 in ?? () </pre><p> afaics the pthread (user provided) destructor keyed to pthread specific data is called on dlunloaded code.<br /><br /> BR,<br /> Pawel. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3926 Trac 1.4.3 anonymous Fri, 12 Feb 2010 23:05:56 GMT attachment set https://svn.boost.org/trac10/ticket/3926 https://svn.boost.org/trac10/ticket/3926 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">tls-test.boost.tgz</span> </li> </ul> Ticket Anthony Williams Mon, 15 Mar 2010 16:03:55 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3926#comment:1 https://svn.boost.org/trac10/ticket/3926#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> When you dlclose a library, you must ensure that no code references that library afterwards. If you have a live thread_specific_ptr with a destructor that belongs to that library then the library must be loaded when the destructor is called. You must therefore ensure that the thread_specific_ptr does not have a value on any thread when the library is unloaded. </p> Ticket pluto@… Mon, 07 Jun 2010 19:29:53 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/3926#comment:2 https://svn.boost.org/trac10/ticket/3926#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">wontfix</span> </li> </ul> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3926#comment:1" title="Comment 1">anthonyw</a>: </p> <blockquote class="citation"> <p> When you dlclose a library, you must ensure that no code references that library afterwards. If you have a live thread_specific_ptr with a destructor that belongs to that library then the library must be loaded when the destructor is called. You must therefore ensure that the thread_specific_ptr does not have a value on any thread when the library is unloaded. </p> </blockquote> <p> the thread_specific_ptr dtor called from dlclose() calls set_tss_data() with boost default cleanup function and *NULL* new_value. what's the point of deleting NULL pointer in cleanup function? this accidentally works in shared libs enviroment beacause the cleanup function exists in memory and 'delete 0' is valid in c++. with dynamically loaded libs glibc tries to call useless cleanup callback from dl-unloaded code and ends with gpf. solution: the thread_specific_ptr dtor should delete current_value and call set_tss_data() in the same way as the release() does. </p> Ticket pluto@… Thu, 10 Jun 2010 14:45:58 GMT <link>https://svn.boost.org/trac10/ticket/3926#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:3</guid> <description> <p> currently there's a crash in boost.thread core. please follow this scenario: </p> <pre class="wiki">start thread. dlopen lib. run function from lib which uses thread_specific_ptr. boost::detail::create_epoch_tss_key registers delete_epoch_tss_data destructor. exit from lib function. dlclose lib (unload delete_epoch_tss_data code). exit thread __nptl_deallocate_tsd tries to call unloaded key destructor and crashes. </pre><p> i think that libs/thread/src/pthread/once.cpp should contain alternative cleanup function with <span class="underline">attributte</span>(( destructor )): </p> <pre class="wiki">if ( pthread_getspecific( epoch_tss_key ) ) pthread_key_delete( epoch_tss_key ) </pre> </description> <category>Ticket</category> </item> <item> <author>pluto@…</author> <pubDate>Fri, 11 Jun 2010 13:14:57 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3926 https://svn.boost.org/trac10/ticket/3926 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost-tls.patch</span> </li> </ul> <p> proposed patch for proper cleanup of the static libboost_thread linked into shared objects. </p> Ticket dadrus Thu, 28 Apr 2011 10:45:05 GMT <link>https://svn.boost.org/trac10/ticket/3926#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:4</guid> <description> <p> The patch provided above is not applicable on apple. At least on Mac OSX 10.5 PTHREAD_ONCE_INIT is defined as </p> <pre class="wiki">#define PTHREAD_ONCE_INIT {_PTHREAD_COND_SIG_init, {0}} </pre><p> and not as </p> <pre class="wiki">#define PTHREAD_ONCE_INIT 0 </pre><p> like on Linux, so one can not use simple compare operator. Here comes the patch, which works on both, linux and mac. I'm still using 1.38 version of boost. So one has to adjust it for newer versions. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>dadrus</dc:creator> <pubDate>Thu, 28 Apr 2011 10:45:53 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3926 https://svn.boost.org/trac10/ticket/3926 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_thread.patch</span> </li> </ul> <p> patch for linux and mac </p> Ticket dadrus Thu, 28 Apr 2011 10:57:35 GMT <link>https://svn.boost.org/trac10/ticket/3926#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:5</guid> <description> <p> There is a small typo in my last comment. On Mac PTHREAD_ONCE_INIT is defined as follows: </p> <pre class="wiki">#define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {0}} </pre><p> I would like also to ask you Anthony to tackle this ticket soon. Hopefully for the next boost release. </p> <p> Regards<br /> </p> <p> Dimitrij </p> </description> <category>Ticket</category> </item> <item> <author>tkramer@…</author> <pubDate>Fri, 22 Jul 2011 12:28:28 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:6</guid> <description> <p> I ran into this recently as well. Any updates on getting this patch committed? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 07 Dec 2011 18:24:27 GMT</pubDate> <title>owner, status, type, milestone changed https://svn.boost.org/trac10/ticket/3926#comment:7 https://svn.boost.org/trac10/ticket/3926#comment:7 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Anthony Williams</span> to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">new</span> </li> <li><strong>type</strong> <span class="trac-field-old">Bugs</span> → <span class="trac-field-new">Patches</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">Boost 1.43.0</span> → <span class="trac-field-new">To Be Determined</span> </li> </ul> Ticket viboes Wed, 07 Dec 2011 22:20:59 GMT <link>https://svn.boost.org/trac10/ticket/3926#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:8</guid> <description> <p> I don't know nothing about dl_open/dl_close. Please, could you explain me when and why delete_epoch_tss_key_on_dlclose will be called? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 07 Dec 2011 22:29:38 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:9</guid> <description> <p> Oh, I see now it is the gcc attributte(( destructor )) that make it be called after main(). </p> <p> Shouldn't this function be added conditionally (when this attribute is available)? </p> <p> What about compilers that don't support this attribute? How the the key will be deleted? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 07 Dec 2011 22:31:57 GMT</pubDate> <title>status changed https://svn.boost.org/trac10/ticket/3926#comment:10 https://svn.boost.org/trac10/ticket/3926#comment:10 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket viboes Sun, 11 Dec 2011 02:07:27 GMT <link>https://svn.boost.org/trac10/ticket/3926#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:11</guid> <description> <p> See also <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4639" title="#4639: Bugs: boost thread library leaks pthread_key (closed: duplicate)">#4639</a> boost thread library leaks pthread_key </p> </description> <category>Ticket</category> </item> <item> <author>pluto@…</author> <pubDate>Sun, 11 Dec 2011 09:28:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:12 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:12</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3926#comment:11" title="Comment 11">viboes</a>: </p> <blockquote class="citation"> <p> See also <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4639" title="#4639: Bugs: boost thread library leaks pthread_key (closed: duplicate)">#4639</a> boost thread library leaks pthread_key </p> </blockquote> <p> yes, the <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4639" title="#4639: Bugs: boost thread library leaks pthread_key (closed: duplicate)">#4639</a> describes the same problem but there's one major issue with both patches. the desctruction order of global objects is not specified in general, especially in these days when recent gnu toolchain can sort .init/.fini-array sections. </p> <p> e.g. the ~delete_epoch_tss_key_on_dlclose_t() from <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4639" title="#4639: Bugs: boost thread library leaks pthread_key (closed: duplicate)">#4639</a> may release pthread_key and after this the ~thread_specific_ptr() may accuire key again, set null handler and finally leak/gpf as usual. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 07 Jan 2012 23:20:57 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:13</guid> <description> <p> See also <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/2470" title="#2470: Support Requests: Problem with threads started in a dynamically loaded bundle under Mac OS X (closed: duplicate)">#2470</a> Problem with threads started in a dynamically loaded bundle under Mac OS X </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Fri, 06 Sep 2013 05:50:46 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:14 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:14</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3926#comment:12" title="Comment 12">pluto@…</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3926#comment:11" title="Comment 11">viboes</a>: </p> <blockquote class="citation"> <p> See also <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4639" title="#4639: Bugs: boost thread library leaks pthread_key (closed: duplicate)">#4639</a> boost thread library leaks pthread_key </p> </blockquote> <p> yes, the <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4639" title="#4639: Bugs: boost thread library leaks pthread_key (closed: duplicate)">#4639</a> describes the same problem but there's one major issue with both patches. the desctruction order of global objects is not specified in general, especially in these days when recent gnu toolchain can sort .init/.fini-array sections. </p> <p> e.g. the ~delete_epoch_tss_key_on_dlclose_t() from <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4639" title="#4639: Bugs: boost thread library leaks pthread_key (closed: duplicate)">#4639</a> may release pthread_key and after this the ~thread_specific_ptr() may accuire key again, set null handler and finally leak/gpf as usual. </p> </blockquote> </description> <category>Ticket</category> </item> <item> <author>kai.dietrich@…</author> <pubDate>Mon, 03 Feb 2014 16:28:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:15 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:15</guid> <description> <p> Hi all, </p> <p> I also got bitten by that one. Our application compiles boost statically into a shared library (.so/linux). Users are supposed to dl_open/dl_close (potentially often). Each open/close cycle leads to a key/handle leak due to boost not freeing the handle and not giving any control over the tls handles to the user. </p> <p> At the moment the tls keys in thread.cpp and once.cpp are internal and not accessible from the outside. Would it be possible to give out a way to the user. The windows implementation also has some pretty verbose tls cleanup code. </p> <p> This bug can be a real production showstopper. I'd give it a way higher priority. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 04 Feb 2014 02:28:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:16 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:16</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3926#comment:15" title="Comment 15">kai.dietrich@…</a>: </p> <blockquote class="citation"> <p> Hi all, </p> <p> I also got bitten by that one. Our application compiles boost statically into a shared library (.so/linux). Users are supposed to dl_open/dl_close (potentially often). Each open/close cycle leads to a key/handle leak due to boost not freeing the handle and not giving any control over the tls handles to the user. </p> <p> At the moment the tls keys in thread.cpp and once.cpp are internal and not accessible from the outside. Would it be possible to give out a way to the user. The windows implementation also has some pretty verbose tls cleanup code. </p> <p> This bug can be a real production showstopper. I'd give it a way higher priority. </p> </blockquote> <p> I know and any help in this direction is welcome. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Tue, 04 Feb 2014 07:45:47 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:17 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:17</guid> <description> <p> As said, the win32 implementation has this: </p> <pre class="wiki"> namespace boost { namespace detail { BOOST_THREAD_DECL void __cdecl on_process_enter() {} BOOST_THREAD_DECL void __cdecl on_thread_enter() {} BOOST_THREAD_DECL void __cdecl on_process_exit() { boost::cleanup_tls_key(); } BOOST_THREAD_DECL void __cdecl on_thread_exit() { ... } } } </pre><p> These functions are then somehow added into the PE image destructor sections (tss_dll.cpp and tss_pe.cpp). This was also buggy in some boost versions and messed up MFC cleanup (which also a tls handle leak) so we just disabled that and call the on_process_exit() function manually. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 08 Sep 2015 17:11:21 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:18 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:18</guid> <description> <p> It seems that <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/11302" title="#11302: Bugs: boost thread doesn't build with BOOST_THREAD_PATCH. (closed: fixed)">#11302</a> contains a patch that solves the issue. </p> <p> Please, could you check it? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 08 Sep 2015 19:24:06 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:19 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:19</guid> <description> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/242cf35c519fc886c13789f1f9a049571fde4cdc"><span class="icon">​</span>https://github.com/boostorg/thread/commit/242cf35c519fc886c13789f1f9a049571fde4cdc</a> </p> </description> <category>Ticket</category> </item> <item> <author>pawels@…</author> <pubDate>Tue, 08 Sep 2015 19:30:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:20 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:20</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3926#comment:18" title="Comment 18">viboes</a>: </p> <blockquote class="citation"> <p> It seems that <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/11302" title="#11302: Bugs: boost thread doesn't build with BOOST_THREAD_PATCH. (closed: fixed)">#11302</a> contains a patch that solves the issue. </p> <p> Please, could you check it? </p> </blockquote> <p> i've reported this testcase many years ago :-) it works with recent patch. please commit and close both tickets. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 23 Sep 2015 23:28:48 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:21 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:21</guid> <description> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/242cf35c519fc886c13789f1f9a049571fde4cdc"><span class="icon">​</span>https://github.com/boostorg/thread/commit/242cf35c519fc886c13789f1f9a049571fde4cdc</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 23 Sep 2015 23:29:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3926#comment:22 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3926#comment:22</guid> <description> <p> So, I can define by default BOOST_THREAD_PATCH. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 23 Sep 2015 23:34:03 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/3926#comment:23 https://svn.boost.org/trac10/ticket/3926#comment:23 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.60.0</span> </li> </ul> Ticket viboes Wed, 23 Sep 2015 23:35:48 GMT type changed https://svn.boost.org/trac10/ticket/3926#comment:24 https://svn.boost.org/trac10/ticket/3926#comment:24 <ul> <li><strong>type</strong> <span class="trac-field-old">Patches</span> → <span class="trac-field-new">Bugs</span> </li> </ul> Ticket viboes Sun, 27 Sep 2015 13:35:58 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3926#comment:25 https://svn.boost.org/trac10/ticket/3926#comment:25 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/730cb550e6d969520c3f39e0ddf5d80351bddf3a"><span class="icon">​</span>https://github.com/boostorg/thread/commit/730cb550e6d969520c3f39e0ddf5d80351bddf3a</a> </p> Ticket viboes Thu, 31 Mar 2016 22:13:53 GMT status changed; resolution, milestone deleted https://svn.boost.org/trac10/ticket/3926#comment:26 https://svn.boost.org/trac10/ticket/3926#comment:26 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> <li><strong>milestone</strong> <span class="trac-field-deleted">Boost 1.60.0</span> </li> </ul> <p> This last change has been rolled back as it is introduce a regression in <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/12049" title="#12049: Bugs: Assertion failure from detached threads during shutdown (closed: fixed)">#12049</a> </p> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/47357de276fe4fc01469f34c1dbf8b26fdbc1c4b"><span class="icon">​</span>https://github.com/boostorg/thread/commit/47357de276fe4fc01469f34c1dbf8b26fdbc1c4b</a> </p> <p> Please, add BOOST_THREAD_PATCH if you need it absolutely. </p> Ticket