Opened 12 years ago
Closed 11 years ago
#4639 closed Bugs (duplicate)
boost thread library leaks pthread_key
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | To Be Determined | Component: | thread |
Version: | Boost 1.44.0 | Severity: | Problem |
Keywords: | pthread_key_create pthread_key_delete | Cc: | viboes |
Description
implementation on Linux of boost::thread_specific_ptr calls pthread_key_create, but never calls pthread_key_delete.
On RHEL 4.6 system pthread_key_create succeeds 1024 times in a row without calling pthread_key_delete. After that point pthread_key_create fails.
Basically there are 2 issues:
- resource leak - boost thread should release acquired resource
- When/if pthread_key_create fails - current (1.44.0) implementation completely ignores return code in release version.
I am attaching test case to illustrate/reproduce problem.
Debug version yields: attempt 512 boost_thread_test_deb.exe: libs/thread/src/pthread/once.cpp:32: void boost::detail::<unnamed>::create_epoch_tss_key(): Assertion `!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data)' failed. Aborted While release version results in following: attempt 512 Segmentation fault
Here is a brief explanation of why I need to dlopen/dlclose same shared object repeatedly:
I am working on apache's module and I am using boost::thread_specific_ptr in my module. I am linking with boost thread library statically.
In our organization apache is being gracefully restarted (apachectl graceful) every hour. During every restart my module is being unloaded (along with boost thread) and loaded back again. This usage scenario gives me 512 restarts/reloads, which translates to 21 days before it segfaults.
After closer examination I found out that even if do not boost::thread_specific_ptr use directly - I am still subject to this problem as boost::thread also uses it. All of the above prevents me from using boost thread library in my project.
Attachments (1)
Change History (7)
by , 12 years ago
Attachment: | tss_test_case.tar.gz added |
---|
comment:1 by , 11 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:2 by , 11 years ago
If I am not mistaken, pthread_key_create is called from 2 places:
- pthread_key_create(&epoch_tss_key...
- pthread_key_create(¤t_thread_tls_key, ... )
(at the moment I am looking at code from 1.48.0 release)
I guess that for both keys appropriate point to call pthread_key_delete would be at moment when boost thread library is being unloaded (or process is being terminated).
comment:3 by , 11 years ago
I'm not aware of library load/unload interfaces.
In another ticket, someone has proposed to use attribute(destructor) or something like that when using gcc. How can a function be called when the library is unloaded with other compilers? Could you give me a pointer or better yet, could you prepare a patch? Which compiler are you using?
comment:4 by , 11 years ago
if you have a global object, which has a dtor. that dtor will get called when module is unloaded, regardless of a compiler.
comment:5 by , 11 years ago
Do you mean something like adding this to once.cpp
namespace { const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT; struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t { ~delete_epoch_tss_key_on_dlclose_t() { if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t))) { pthread_key_delete(epoch_tss_key); } } }; delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose; }
comment:6 by , 11 years ago
Resolution: | → duplicate |
---|---|
Status: | assigned → closed |
Even if the problem doesn't manifest in the same way, it seems the solution should be be same. Duplicate of #3926 thread_specific_ptr + dlopen library causes a SIGSEGV.
When the pthread_key_delete should be called? At exit?