Opened 12 years ago

Closed 11 years ago

#4639 closed Bugs (duplicate)

boost thread library leaks pthread_key

Reported by: gleonid@… 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:

  1. resource leak - boost thread should release acquired resource
  2. 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)

tss_test_case.tar.gz (1013 bytes ) - added by Leonid Gershanovich <gleonid@…> 12 years ago.

Download all attachments as: .zip

Change History (7)

by Leonid Gershanovich <gleonid@…>, 12 years ago

Attachment: tss_test_case.tar.gz added

comment:1 by viboes, 11 years ago

Cc: viboes added
Owner: changed from Anthony Williams to viboes
Status: newassigned

When the pthread_key_delete should be called? At exit?

comment:2 by anonymous, 11 years ago

If I am not mistaken, pthread_key_create is called from 2 places:

  1. pthread_key_create(&epoch_tss_key...
  2. pthread_key_create(&current_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 viboes, 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?

Last edited 11 years ago by viboes (previous) (diff)

comment:4 by anonymous, 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 viboes, 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 viboes, 11 years ago

Resolution: duplicate
Status: assignedclosed

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.

Note: See TracTickets for help on using tickets.