Bug 25409 - STL mt_allocator crash in global construcutor
Summary: STL mt_allocator crash in global construcutor
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-12-14 11:42 UTC by Neil Bird
Modified: 2006-03-20 08:48 UTC (History)
1 user (show)

See Also:
Host: i386-redhat-linux
Target: i386-redhat-linux
Build: i386-redhat-linux
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Example of the crash (6.04 KB, application/octet-stream)
2005-12-14 11:44 UTC, Neil Bird
Details
example of how to do testcase (338 bytes, text/plain)
2006-03-17 19:04 UTC, Benjamin Kosnik
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Neil Bird 2005-12-14 11:42:17 UTC
[ I've raised this against 4.2 as I've verified that it's still an issue for that branch, but it's also valid for 4.0.2 & 4.1 ]

  I have a crash in some code that dlopen()s a library (with a static <deque> constructor), which happens to be dependant upon another couple of libraries, one of which uses libpthread.

  The crash occurs in the static library construction mt_allocator.h, within _M_adjust_freelist:

      void
      _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block,
                         size_t __thread_id)
      {
        if (__gthread_active_p())
          {
            __block->_M_thread_id = __thread_id;
HERE ->     --__bin._M_free[__thread_id];
            ++__bin._M_used[__thread_id];
          }
      }

  At the point at which it happens, _M_free is NULL.

  I've done some investigation, and the mal-initialisation is caused by __gthread_active_p() sometimes returning '1' [e.g.,in mt_allocator.h's __pool<true>::_M_initialize_once()] and '0':

  __common_pool_base<_PoolTp,true>::_S_initialize_once() calls this _M_initialise_once() [if I'm right], which runs down to mt_allocator.cc's __pool<true>::_M_initialize().  At this point, __gthread_active_p() returns /0/, (even though it's only just previously returned 1) and the routine doesn't seem to quite know how to handle it, leaving the bin(s) uninitialised.


  I found this problem using Fedora Core's 4.0.1/4.0.2 but have replicated it with vanilla builds with mt_allocator enabled.  This *may* be a dup. of PR 24071;  I'm not sure it's exactly the same, but I feel we may be circling round the same issue.

  Redhat's https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=165728 may also be relevant.

  I'm fairly confident that the GLIBCXX_FORCE_NEW env. var. makes things work properly.  I've also found that, instead, the semi-documented '-pthread' compilation [from the above PR] option makes things work OK too [semi-documented as it's listed as being PPC/Sparc/HP-UX specific, whereas this is a basic 32-bit i686 system].

  The last thing I tried which *also* made things work on its own (ref,. the RedHat report) was to link my test util. (the one that does the dlopen()) with '-lpthread'.
Comment 1 Neil Bird 2005-12-14 11:44:24 UTC
Created attachment 10484 [details]
Example of the crash

Do 'make' in top level of build tree.

'make symbolcheck' afterwards just demos the crash.
Comment 2 Benjamin Kosnik 2006-03-03 18:03:08 UTC
>I've also found that, instead, the semi-documented '-pthread'
>compilation [from the above PR] option makes things work OK too

It is a good idea to use -pthread when compiling code that uses threads on linux. 

I cannot reproduce your example with 4.1.0, or mainline, on linux.

-benjamin
Comment 3 Neil Bird 2006-03-08 12:41:55 UTC
Was it compiled up to use mt_allocator?  I won't have the time to check again for a short while.

If it's considered a good idea to use -pthreads, then it ought really to have it's info-page entry updated to not make it platform specific.
Comment 4 Benjamin Kosnik 2006-03-16 08:40:54 UTC
I'm going to check this in to libstdcxx_so_7-branch. It will be easier to test there.

Please try to make a self-contained testcase for this, ie one file, no make file, etc.

-benjamin
Comment 5 Benjamin Kosnik 2006-03-17 19:04:16 UTC
Created attachment 11064 [details]
example of how to do testcase


Explicitly use __mt_alloc.
Comment 6 Benjamin Kosnik 2006-03-17 19:10:01 UTC
I'm closing this. I cannot reproduce it. In addition, the submitted testcase is not sufficient: it has a complicated directory structure, makefiles, etc etc. Also, does not demonstrate the so-called bug...

Please read:
http://gcc.gnu.org/bugs.html

For the record, using -pthread is mandatory for pthread code. In fact, on mainline  this is now more obvious due to the weakref patches. I am sympathetic to the problems with the gcc manual, which seem to indicate that -pthread is a arch-specific flag. I suggest you file a new bug report about this specific issue.

best,
benjamin
Comment 7 Neil Bird 2006-03-20 08:48:02 UTC
Fair enough;  for the record, I did spend an obscene amount of time trying to make the example more straightforward, but *any* simplification over what I attached worked OK.