[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