Manually cleaning up TSS data in boost 1.49

Hi, I am using boost::thread for a plug-in that is loaded by a third-party Linux application. I have no control over the host's threading or when it chooses to unload my code. Unfortunately I experience a crash every time the host thread unloads the .so and terminates. I get the following backtrace: (gdb) bt #0 0x00007fffde12c460 in ?? () #1 0x00000032cf607889 in start_thread () from /lib64/libpthread.so.0 #2 0x00000032cf2e5ccd in clone () from /lib64/libc.so.6 Not much to go on... I am pretty confident the crash is happening in a pthread key destructor registered by Boost. The only parts of the boost::thread library I am currently using are the synchronization classes: shared_mutex, shared_lock, unique_lock, upgrade_lock, upgrade_to_unique_lock I'm not directly using any thread-specific storage myself. What I would like to do is force boost to call its TSS destructor in my plug-in's destroy_dso() function. Is this at all possible? Many thanks, - Andrew

Le 26/11/12 22:12, Andrew Harvey a écrit :
Hi,
I am using boost::thread for a plug-in that is loaded by a third-party Linux application. I have no control over the host's threading or when it chooses to unload my code.
Unfortunately I experience a crash every time the host thread unloads the .so and terminates. I get the following backtrace:
(gdb) bt #0 0x00007fffde12c460 in ?? () #1 0x00000032cf607889 in start_thread () from /lib64/libpthread.so.0 #2 0x00000032cf2e5ccd in clone () from /lib64/libc.so.6
Not much to go on...
There are several limitation on Boost.Thread that could make this error. I've not yet the knowledge to fix them.
I am pretty confident the crash is happening in a pthread key destructor registered by Boost. The only parts of the boost::thread library I am currently using are the synchronization classes:
shared_mutex, shared_lock, unique_lock, upgrade_lock, upgrade_to_unique_lock
I'm not directly using any thread-specific storage myself.
What I would like to do is force boost to call its TSS destructor in my plug-in's destroy_dso() function. Is this at all possible?
I don't know which version are you using. For the next release I'm preparing a version that could work without thread interruptions. This should allow to use the synchronization part independently of the boost::thread part, so maybe it could be possible to use the library as a header only one. I will try to test it soon. You could check it on your side, by defining BOOST_THREAD_VERSION to 3 and define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS. You will need to link additionally to boost_system and boost_chrono if you are using the Boost.Chrono time related interface. HTH, Vicente

Hi Vicente - thanks for your quick response. I am using Boost 1.49. A few of the third-party libraries I rely on do not yet work with later versions. I had a look through the thread.cpp source code and noticed there is a variable called current_thread_tls_key. This is exactly the information I need to do my own cleanup. However it is hidden away within the file's anonymous namespace (for very good reasons, no doubt!) That said, is there any way to access it? I would the be able to call pthread_key_delete() on it and hopefully prevent my host application from crashing. Regards, - Andrew 07779 090534 arharvey.com On 26 November 2012 23:05, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Le 26/11/12 22:12, Andrew Harvey a écrit :
Hi,
I am using boost::thread for a plug-in that is loaded by a third-party Linux application. I have no control over the host's threading or when it chooses to unload my code.
Unfortunately I experience a crash every time the host thread unloads the .so and terminates. I get the following backtrace:
(gdb) bt #0 0x00007fffde12c460 in ?? () #1 0x00000032cf607889 in start_thread () from /lib64/libpthread.so.0 #2 0x00000032cf2e5ccd in clone () from /lib64/libc.so.6
Not much to go on...
There are several limitation on Boost.Thread that could make this error.
I've not yet the knowledge to fix them.
registered by Boost. The only parts of the boost::thread library I am currently using are the synchronization classes:
shared_mutex, shared_lock, unique_lock, upgrade_lock, upgrade_to_unique_lock
I'm not directly using any thread-specific storage myself.
What I would like to do is force boost to call its TSS destructor in my plug-in's destroy_dso() function. Is this at all possible?
I don't know which version are you using. For the next release I'm
I am pretty confident the crash is happening in a pthread key destructor preparing a version that could work without thread interruptions. This should allow to use the synchronization part independently of the boost::thread part, so maybe it could be possible to use the library as a header only one. I will try to test it soon. You could check it on your side, by defining BOOST_THREAD_VERSION to 3 and define BOOST_THREAD_DONT_PROVIDE_**INTERRUPTIONS. You will need to link additionally to boost_system and boost_chrono if you are using the Boost.Chrono time related interface.
HTH, Vicente
______________________________**_________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/**mailman/listinfo.cgi/boost-**usershttp://lists.boost.org/mailman/listinfo.cgi/boost-users

Le 27/11/12 00:46, Andrew Harvey a écrit :
Hi Vicente - thanks for your quick response.
Please don't top post in this ML.
I am using Boost 1.49. A few of the third-party libraries I rely on do not yet work with later versions.
I had a look through the thread.cpp source code and noticed there is a variable called current_thread_tls_key. This is exactly the information I need to do my own cleanup. However it is hidden away within the file's anonymous namespace (for very good reasons, no doubt!) That said, is there any way to access it? I would the be able to call pthread_key_delete() on it and hopefully prevent my host application from crashing.
You could always add a function that retrieves it. I don't master this part of Boost.Thread enough to tell you if this could be enough. Best, Vicente

On 27 November 2012 18:55, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Le 27/11/12 00:46, Andrew Harvey a écrit : You could always add a function that retrieves it. I don't master this part of Boost.Thread enough to tell you if this could be enough.
Hi,
In the end I didn't really want to maintain my own Boost fork, so I came up
with another solution.
The fundamental problem was that the host application, which I have no
control over, was unloading my plug-in before the thread had a chance to
call the pthread TSS destructor. When the thread did end, a jump to invalid
memory would result.
My workaround is to ensure that the plug-in's code is never actually
deallocated. I do this by finding the path of the dynamic library and
re-loading it myself. Since the library is already in memory, all this does
is increment its reference count by one. When the host application later
unloads the plug-in, the reference count is decremented but remains
non-zero.
Admittedly, it's a hack and platform-specific, but for my specific needs it
works. This may be one option for people who run into similar problems.
#include <iostream>
#include

Le 05/12/12 16:25, Andrew Harvey a écrit :
On 27 November 2012 18:55, Vicente J. Botet Escriba
mailto:vicente.botet@wanadoo.fr> wrote: Le 27/11/12 00:46, Andrew Harvey a écrit : You could always add a function that retrieves it. I don't master this part of Boost.Thread enough to tell you if this could be enough.
Hi,
In the end I didn't really want to maintain my own Boost fork, so I came up with another solution.
The fundamental problem was that the host application, which I have no control over, was unloading my plug-in before the thread had a chance to call the pthread TSS destructor. When the thread did end, a jump to invalid memory would result.
My workaround is to ensure that the plug-in's code is never actually deallocated. I do this by finding the path of the dynamic library and re-loading it myself. Since the library is already in memory, all this does is increment its reference count by one. When the host application later unloads the plug-in, the reference count is decremented but remains non-zero.
Admittedly, it's a hack and platform-specific, but for my specific needs it works. This may be one option for people who run into similar problems.
Glad to see that you have found a workaround as at present I don't have a fix. Best, Vicente
participants (2)
-
Andrew Harvey
-
Vicente J. Botet Escriba