forked from OSchip/llvm-project
[msan] Get stack limits with pthread_create interceptor.
Before we did it lazily on the first stack unwind in the thread. It resulted in deadlock when the unwind was caused by memory allocation inside pthread_getattr_np: pthread_getattr_np <<< not reentable GetThreadStackTopAndBottom __interceptor_realloc pthread_getattr_np llvm-svn: 197026
This commit is contained in:
parent
338d70c0bb
commit
cd07898cf8
|
@ -0,0 +1,22 @@
|
|||
// RUN: %clangxx_msan -m64 -fsanitize-memory-track-origins -O0 %s -o %t && %t
|
||||
|
||||
// Regression test for a deadlock in pthread_getattr_np
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void *ThreadFn(void *) {
|
||||
pthread_attr_t attr;
|
||||
int res = pthread_getattr_np(pthread_self(), &attr);
|
||||
assert(!res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
pthread_t t;
|
||||
int res = pthread_create(&t, 0, ThreadFn, 0);
|
||||
assert(!res);
|
||||
res = pthread_join(t, 0);
|
||||
assert(!res);
|
||||
return 0;
|
||||
}
|
|
@ -59,9 +59,7 @@ THREADLOCAL u64 __msan_va_arg_overflow_size_tls;
|
|||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
THREADLOCAL u32 __msan_origin_tls;
|
||||
|
||||
static THREADLOCAL struct {
|
||||
uptr stack_top, stack_bottom;
|
||||
} __msan_stack_bounds;
|
||||
THREADLOCAL MsanStackBounds msan_stack_bounds;
|
||||
|
||||
static THREADLOCAL int is_in_symbolizer;
|
||||
static THREADLOCAL int is_in_loader;
|
||||
|
@ -168,19 +166,6 @@ static void InitializeFlags(Flags *f, const char *options) {
|
|||
ParseFlagsFromString(f, options);
|
||||
}
|
||||
|
||||
static void GetCurrentStackBounds(uptr *stack_top, uptr *stack_bottom) {
|
||||
if (__msan_stack_bounds.stack_top == 0) {
|
||||
// Break recursion (GetStackTrace -> GetThreadStackTopAndBottom ->
|
||||
// realloc -> GetStackTrace).
|
||||
__msan_stack_bounds.stack_top = __msan_stack_bounds.stack_bottom = 1;
|
||||
GetThreadStackTopAndBottom(/* at_initialization */false,
|
||||
&__msan_stack_bounds.stack_top,
|
||||
&__msan_stack_bounds.stack_bottom);
|
||||
}
|
||||
*stack_top = __msan_stack_bounds.stack_top;
|
||||
*stack_bottom = __msan_stack_bounds.stack_bottom;
|
||||
}
|
||||
|
||||
void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
|
||||
bool request_fast_unwind) {
|
||||
if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
|
||||
|
@ -188,9 +173,8 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
|
|||
SymbolizerScope sym_scope;
|
||||
return stack->Unwind(max_s, pc, bp, 0, 0, request_fast_unwind);
|
||||
}
|
||||
uptr stack_top, stack_bottom;
|
||||
GetCurrentStackBounds(&stack_top, &stack_bottom);
|
||||
stack->Unwind(max_s, pc, bp, stack_top, stack_bottom, request_fast_unwind);
|
||||
stack->Unwind(max_s, pc, bp, msan_stack_bounds.stack_top,
|
||||
msan_stack_bounds.stack_bottom, request_fast_unwind);
|
||||
}
|
||||
|
||||
void PrintWarning(uptr pc, uptr bp) {
|
||||
|
@ -340,9 +324,9 @@ void __msan_init() {
|
|||
}
|
||||
Symbolizer::Get()->AddHooks(EnterSymbolizer, ExitSymbolizer);
|
||||
|
||||
GetThreadStackTopAndBottom(/* at_initialization */true,
|
||||
&__msan_stack_bounds.stack_top,
|
||||
&__msan_stack_bounds.stack_bottom);
|
||||
GetThreadStackTopAndBottom(/* at_initialization */ true,
|
||||
&msan_stack_bounds.stack_top,
|
||||
&msan_stack_bounds.stack_bottom);
|
||||
VPrintf(1, "MemorySanitizer init done\n");
|
||||
msan_init_is_running = 0;
|
||||
msan_inited = 1;
|
||||
|
|
|
@ -106,4 +106,10 @@ class ScopedThreadLocalStateBackup {
|
|||
#define MSAN_FREE_HOOK(ptr) \
|
||||
if (&__msan_free_hook) __msan_free_hook(ptr)
|
||||
|
||||
struct MsanStackBounds {
|
||||
uptr stack_top, stack_bottom;
|
||||
};
|
||||
|
||||
extern THREADLOCAL MsanStackBounds msan_stack_bounds;
|
||||
|
||||
#endif // MSAN_H
|
||||
|
|
|
@ -1088,6 +1088,10 @@ static void *MsanThreadStartFunc(void *arg) {
|
|||
Die();
|
||||
}
|
||||
atomic_store(&p->done, 1, memory_order_release);
|
||||
|
||||
GetThreadStackTopAndBottom(/* at_initialization */ false,
|
||||
&msan_stack_bounds.stack_top,
|
||||
&msan_stack_bounds.stack_bottom);
|
||||
return callback(param);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue