[LLVMbugs] [Bug 12109] New: Registration of CrashHandler in lib/Support/PrettyStackTraceEntry::PrettyStackTraceEntry() not thread-safe causing crash

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Feb 28 04:20:45 PST 2012


http://llvm.org/bugs/show_bug.cgi?id=12109

             Bug #: 12109
           Summary: Registration of CrashHandler in
                    lib/Support/PrettyStackTraceEntry::PrettyStackTraceEnt
                    ry() not thread-safe causing crash
           Product: libraries
           Version: 2.9
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Support Libraries
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: iboehm at synopsys.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


The registration of a CrashPrinter in
lib/Support/PrettyStackTraceEntry::PrettyStackTraceEntry() is not
thread-safe. Please see the followings link for a more detailed discussion of
the issue:
-
http://eli.thegreenplace.net/2011/08/30/construction-of-function-static-variables-in-c-is-not-thread-safe/

For us the issue occurs with LLVM 2.9, 3.0 and trunk also cause the problem as
the problematic
portion of code has not changed.

Here is the offending snippet of source code marked up with '^^^' at the
offending line:

<snip: lib/Support/PrettyStackTraceEntry.cpp>

static bool RegisterCrashPrinter() {
  if (!DisablePrettyStackTrace)
    sys::AddSignalHandler(CrashHandler, 0);
  return false;
}

PrettyStackTraceEntry::PrettyStackTraceEntry() {
  // The first time this is called, we register the crash printer.
  static bool HandlerRegistered = RegisterCrashPrinter();
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  (void)HandlerRegistered;

  // Link ourselves.
  NextEntry = PrettyStackTraceHead.get();
  PrettyStackTraceHead.set(this);
}

</snap: lib/Support/PrettyStackTraceEntry.cpp>

As this problem eventually boils down to a race-condition it is not so easy to
reproduce it.
In our setting we run into this issue 1 out of 10 times.

Here is a stack trace showing the problem (irrelevant class names and method
names obfuscated):
------------------------------------------------------------------------------------------

terminate called after throwing an instance of '__gnu_cxx::recursive_init'
  what():  N9__gnu_cxx14recursive_initE

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x45e3b90 (LWP 19656)]
0x0096c410 in __kernel_vsyscall ()
(gdb) where
#0  0x0096c410 in __kernel_vsyscall ()
#1  0x00af0df0 in raise () from /lib/libc.so.6
#2  0x00af2701 in abort () from /lib/libc.so.6
#3  0x00403b50 in __gnu_cxx::__verbose_terminate_handler() () from
/usr/lib/libstdc++.so.6
#4  0x00401555 in ?? () from /usr/lib/libstdc++.so.6
#5  0x00401592 in std::terminate() () from /usr/lib/libstdc++.so.6
#6  0x004016ca in __cxa_throw () from /usr/lib/libstdc++.so.6
#7  0x00401995 in __cxa_guard_acquire () from /usr/lib/libstdc++.so.6
#8  0x031c7415 in llvm::PrettyStackTraceEntry::PrettyStackTraceEntry
(this=0x45e23d0)
    at /disk/scratch/clang.llvm/rel/2.9/lib/Support/PrettyStackTrace.cpp:109
#9  0x0244d463 in
clang::PrettyStackTraceParserEntry::PrettyStackTraceParserEntry
(this=0x45e23d0, p=...)
    at
/disk/scratch/clang.llvm/rel/2.9/tools/clang/lib/Parse/../../include/clang/Parse/Parser.h:42
#10 0x02449cb7 in clang::Parser::Parser (this=0x45e23cc, pp=..., actions=...)
at /disk/scratch/clang.llvm/rel/2.9/tools/clang/lib/Parse/Parser.cpp:27
#11 0x0242cba4 in clang::ParseAST (S=..., PrintStats=false) at
/disk/scratch/clang.llvm/rel/2.9/tools/clang/lib/Parse/ParseAST.cpp:53
#12 0x0242ce65 in clang::ParseAST (PP=..., Consumer=0xb7e05380, Ctx=...,
PrintStats=false, CompleteTranslationUnit=true, CompletionConsumer=0x0)
    at /disk/scratch/clang.llvm/rel/2.9/tools/clang/lib/Parse/ParseAST.cpp:41
#13 0x021cb596 in DDD::bar (this=0xad57480, m=...) at DDD.cpp:440
#14 0x021cc7e0 in CCC::foo (this=0xad57480, wu=...) at CCC.cpp:408
#15 0x021cc90c in BBB::run (this=0xad57480) at BBB.cpp:273
#16 0x02132518 in AAA::thread_entry_point (arg=0xad57480) at AAA.cpp:113
#17 0x00318832 in start_thread () from /lib/libpthread.so.0
#18 0x00b9a45e in clone () from /lib/libc.so.6
------ STACK TRACE ----

------------------------------------------------------------------------------------------

Uncommenting the registration of the CrashHandler makes the problem go away
which is
another indicator that the CrashHandler registration is indeed at fault. 

Maybe a solution along the lines of
'http://stackoverflow.com/questions/6479604/how-can-i-avoid-static-data-member-init-fiasco-in-a-thread-safe-way'
would be suitable here. Unfortunately in the context of PrettyStackTraceEntry
it should
be possible to disable the registration of a CrashHandler by setting
'DisablePrettyStackTrace'
to true from an external agent, which would then not work anymore as static
initialisation would
happen before that.

To fix the issue one must install the CrashHandler in a thread-safe way AND
still allow
external agents to disable its registration.

Best regards,
Igor

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list