tsan: intercept _exit so that we can override exit status
llvm-svn: 191898
This commit is contained in:
parent
5ba736457c
commit
e07dc7d1fe
|
@ -75,6 +75,9 @@ struct Flags {
|
||||||
int flush_memory_ms;
|
int flush_memory_ms;
|
||||||
// Flush symbolizer caches every X ms.
|
// Flush symbolizer caches every X ms.
|
||||||
int flush_symbolizer_ms;
|
int flush_symbolizer_ms;
|
||||||
|
// Resident memory limit in MB to aim at.
|
||||||
|
// If the process consumes more memory, then TSan will flush shadow memory.
|
||||||
|
int memory_limit_mb;
|
||||||
// Stops on start until __tsan_resume() is called (for debugging).
|
// Stops on start until __tsan_resume() is called (for debugging).
|
||||||
bool stop_on_start;
|
bool stop_on_start;
|
||||||
// Controls whether RunningOnValgrind() returns true or false.
|
// Controls whether RunningOnValgrind() returns true or false.
|
||||||
|
|
|
@ -1958,8 +1958,27 @@ static void syscall_post_fork(uptr pc, int res) {
|
||||||
syscall_post_fork(GET_CALLER_PC(), res)
|
syscall_post_fork(GET_CALLER_PC(), res)
|
||||||
#include "sanitizer_common/sanitizer_common_syscalls.inc"
|
#include "sanitizer_common/sanitizer_common_syscalls.inc"
|
||||||
|
|
||||||
|
TSAN_INTERCEPTOR(void, _exit, int status) {
|
||||||
|
ThreadState * thr = cur_thread();
|
||||||
|
int status1 = Finalize(thr);
|
||||||
|
REAL(fflush)(0);
|
||||||
|
if (status == 0)
|
||||||
|
status = status1;
|
||||||
|
REAL(_exit)(status);
|
||||||
|
}
|
||||||
|
|
||||||
namespace __tsan {
|
namespace __tsan {
|
||||||
|
|
||||||
|
static void finalize(void *arg) {
|
||||||
|
ThreadState * thr = cur_thread();
|
||||||
|
uptr pc = 0;
|
||||||
|
atexit_ctx->exit(thr, pc);
|
||||||
|
int status = Finalize(thr);
|
||||||
|
REAL(fflush)(0);
|
||||||
|
if (status)
|
||||||
|
REAL(_exit)(status);
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessPendingSignals(ThreadState *thr) {
|
void ProcessPendingSignals(ThreadState *thr) {
|
||||||
CHECK_EQ(thr->in_rtl, 0);
|
CHECK_EQ(thr->in_rtl, 0);
|
||||||
SignalContext *sctx = SigCtx(thr);
|
SignalContext *sctx = SigCtx(thr);
|
||||||
|
@ -2009,16 +2028,6 @@ void ProcessPendingSignals(ThreadState *thr) {
|
||||||
thr->in_signal_handler = false;
|
thr->in_signal_handler = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finalize(void *arg) {
|
|
||||||
ThreadState * thr = cur_thread();
|
|
||||||
uptr pc = 0;
|
|
||||||
atexit_ctx->exit(thr, pc);
|
|
||||||
int status = Finalize(cur_thread());
|
|
||||||
REAL(fflush)(0);
|
|
||||||
if (status)
|
|
||||||
_exit(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void unreachable() {
|
static void unreachable() {
|
||||||
Printf("FATAL: ThreadSanitizer: unreachable called\n");
|
Printf("FATAL: ThreadSanitizer: unreachable called\n");
|
||||||
Die();
|
Die();
|
||||||
|
@ -2199,6 +2208,7 @@ void InitializeInterceptors() {
|
||||||
TSAN_INTERCEPT(dlclose);
|
TSAN_INTERCEPT(dlclose);
|
||||||
TSAN_INTERCEPT(on_exit);
|
TSAN_INTERCEPT(on_exit);
|
||||||
TSAN_INTERCEPT(__cxa_atexit);
|
TSAN_INTERCEPT(__cxa_atexit);
|
||||||
|
TSAN_INTERCEPT(_exit);
|
||||||
|
|
||||||
// Need to setup it, because interceptors check that the function is resolved.
|
// Need to setup it, because interceptors check that the function is resolved.
|
||||||
// But atexit is emitted directly into the module, so can't be resolved.
|
// But atexit is emitted directly into the module, so can't be resolved.
|
||||||
|
|
|
@ -142,6 +142,7 @@ void StatOutput(u64 *stat) {
|
||||||
name[StatInt_strcasecmp] = " strcasecmp ";
|
name[StatInt_strcasecmp] = " strcasecmp ";
|
||||||
name[StatInt_strncasecmp] = " strncasecmp ";
|
name[StatInt_strncasecmp] = " strncasecmp ";
|
||||||
name[StatInt_atexit] = " atexit ";
|
name[StatInt_atexit] = " atexit ";
|
||||||
|
name[StatInt__exit] = " _exit ";
|
||||||
name[StatInt___cxa_guard_acquire] = " __cxa_guard_acquire ";
|
name[StatInt___cxa_guard_acquire] = " __cxa_guard_acquire ";
|
||||||
name[StatInt___cxa_guard_release] = " __cxa_guard_release ";
|
name[StatInt___cxa_guard_release] = " __cxa_guard_release ";
|
||||||
name[StatInt___cxa_guard_abort] = " __cxa_guard_abort ";
|
name[StatInt___cxa_guard_abort] = " __cxa_guard_abort ";
|
||||||
|
|
|
@ -139,6 +139,7 @@ enum StatType {
|
||||||
StatInt_strstr,
|
StatInt_strstr,
|
||||||
StatInt_strdup,
|
StatInt_strdup,
|
||||||
StatInt_atexit,
|
StatInt_atexit,
|
||||||
|
StatInt__exit,
|
||||||
StatInt___cxa_guard_acquire,
|
StatInt___cxa_guard_acquire,
|
||||||
StatInt___cxa_guard_release,
|
StatInt___cxa_guard_release,
|
||||||
StatInt___cxa_guard_abort,
|
StatInt___cxa_guard_abort,
|
||||||
|
|
Loading…
Reference in New Issue