forked from OSchip/llvm-project
tsan: fix false positive related to signals
Write interceptor calls malloc, which causes a false unsafe-call-in-signal-handler report. See the test. llvm-svn: 219784
This commit is contained in:
parent
a08a8dc01d
commit
6373829449
|
@ -48,7 +48,8 @@ static bool bogusfd(int fd) {
|
|||
}
|
||||
|
||||
static FdSync *allocsync(ThreadState *thr, uptr pc) {
|
||||
FdSync *s = (FdSync*)user_alloc(thr, pc, sizeof(FdSync));
|
||||
FdSync *s = (FdSync*)user_alloc(thr, pc, sizeof(FdSync), kDefaultAlignment,
|
||||
false);
|
||||
atomic_store(&s->rc, 1, memory_order_relaxed);
|
||||
return s;
|
||||
}
|
||||
|
@ -65,7 +66,7 @@ static void unref(ThreadState *thr, uptr pc, FdSync *s) {
|
|||
CHECK_NE(s, &fdctx.globsync);
|
||||
CHECK_NE(s, &fdctx.filesync);
|
||||
CHECK_NE(s, &fdctx.socksync);
|
||||
user_free(thr, pc, s);
|
||||
user_free(thr, pc, s, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,13 +79,13 @@ static FdDesc *fddesc(ThreadState *thr, uptr pc, int fd) {
|
|||
if (l1 == 0) {
|
||||
uptr size = kTableSizeL2 * sizeof(FdDesc);
|
||||
// We need this to reside in user memory to properly catch races on it.
|
||||
void *p = user_alloc(thr, pc, size);
|
||||
void *p = user_alloc(thr, pc, size, kDefaultAlignment, false);
|
||||
internal_memset(p, 0, size);
|
||||
MemoryResetRange(thr, (uptr)&fddesc, (uptr)p, size);
|
||||
if (atomic_compare_exchange_strong(pl1, &l1, (uptr)p, memory_order_acq_rel))
|
||||
l1 = (uptr)p;
|
||||
else
|
||||
user_free(thr, pc, p);
|
||||
user_free(thr, pc, p, false);
|
||||
}
|
||||
return &((FdDesc*)l1)[fd % kTableSizeL2]; // NOLINT
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ static void SignalUnsafeCall(ThreadState *thr, uptr pc) {
|
|||
}
|
||||
}
|
||||
|
||||
void *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align) {
|
||||
void *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align, bool signal) {
|
||||
if ((sz >= (1ull << 40)) || (align >= (1ull << 40)))
|
||||
return AllocatorReturnNull();
|
||||
void *p = allocator()->Allocate(&thr->alloc_cache, sz, align);
|
||||
|
@ -84,15 +84,17 @@ void *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align) {
|
|||
return 0;
|
||||
if (ctx && ctx->initialized)
|
||||
OnUserAlloc(thr, pc, (uptr)p, sz, true);
|
||||
SignalUnsafeCall(thr, pc);
|
||||
if (signal)
|
||||
SignalUnsafeCall(thr, pc);
|
||||
return p;
|
||||
}
|
||||
|
||||
void user_free(ThreadState *thr, uptr pc, void *p) {
|
||||
void user_free(ThreadState *thr, uptr pc, void *p, bool signal) {
|
||||
if (ctx && ctx->initialized)
|
||||
OnUserFree(thr, pc, (uptr)p, true);
|
||||
allocator()->Deallocate(&thr->alloc_cache, p);
|
||||
SignalUnsafeCall(thr, pc);
|
||||
if (signal)
|
||||
SignalUnsafeCall(thr, pc);
|
||||
}
|
||||
|
||||
void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) {
|
||||
|
|
|
@ -26,9 +26,9 @@ void AllocatorPrintStats();
|
|||
|
||||
// For user allocations.
|
||||
void *user_alloc(ThreadState *thr, uptr pc, uptr sz,
|
||||
uptr align = kDefaultAlignment);
|
||||
uptr align = kDefaultAlignment, bool signal = true);
|
||||
// Does not accept NULL.
|
||||
void user_free(ThreadState *thr, uptr pc, void *p);
|
||||
void user_free(ThreadState *thr, uptr pc, void *p, bool signal = true);
|
||||
void *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz);
|
||||
void *user_alloc_aligned(ThreadState *thr, uptr pc, uptr sz, uptr align);
|
||||
uptr user_alloc_usable_size(const void *p);
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void handler(int, siginfo_t*, void*) {
|
||||
const char *str = "HELLO FROM SIGNAL\n";
|
||||
write(2, str, strlen(str));
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct sigaction act = {};
|
||||
act.sa_sigaction = &handler;
|
||||
sigaction(SIGPROF, &act, 0);
|
||||
kill(getpid(), SIGPROF);
|
||||
sleep(1);
|
||||
fprintf(stderr, "DONE\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK-NOT: WARNING: ThreadSanitizer
|
||||
// CHECK: HELLO FROM SIGNAL
|
||||
// CHECK: DONE
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
|
||||
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// Always enable asserts.
|
||||
#ifdef NDEBUG
|
||||
|
@ -37,7 +37,7 @@ int main() {
|
|||
|
||||
// Restore the original set.
|
||||
assert(0 == sigprocmask(SIG_SETMASK, &old_set, NULL));
|
||||
printf("DONE");
|
||||
printf("DONE\n");
|
||||
}
|
||||
|
||||
// CHECK: HANDLER
|
||||
|
|
Loading…
Reference in New Issue