forked from OSchip/llvm-project
asan: fix signal handling during stoptheworld
The problem is that without SA_RESTORER flag, kernel ignores the handler. So tracer actually did not setup any handler. Add SA_RESTORER flag when setting up handlers. Add a test that causes SIGSEGV in stoptheworld callback. Move SignalContext from asan to sanitizer_common to print better diagnostics about signal in the tracer thread. http://reviews.llvm.org/D8005 llvm-svn: 230978
This commit is contained in:
parent
d61f7d8c39
commit
b79ac88155
|
@ -62,21 +62,6 @@ namespace __asan {
|
|||
class AsanThread;
|
||||
using __sanitizer::StackTrace;
|
||||
|
||||
struct SignalContext {
|
||||
void *context;
|
||||
uptr addr;
|
||||
uptr pc;
|
||||
uptr sp;
|
||||
uptr bp;
|
||||
|
||||
SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp) :
|
||||
context(context), addr(addr), pc(pc), sp(sp), bp(bp) {
|
||||
}
|
||||
|
||||
// Creates signal context in a platform-specific manner.
|
||||
static SignalContext Create(void *siginfo, void *context);
|
||||
};
|
||||
|
||||
void AsanInitFromRtl();
|
||||
|
||||
// asan_rtl.cc
|
||||
|
@ -90,7 +75,6 @@ void *AsanDoesNotSupportStaticLinkage();
|
|||
void AsanCheckDynamicRTPrereqs();
|
||||
void AsanCheckIncompatibleRT();
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
|
||||
void AsanOnSIGSEGV(int, void *siginfo, void *context);
|
||||
|
||||
void DisableReexec();
|
||||
|
|
|
@ -152,78 +152,6 @@ void AsanCheckIncompatibleRT() {
|
|||
}
|
||||
#endif // SANITIZER_ANDROID
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
|
||||
#if defined(__arm__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.arm_pc;
|
||||
*bp = ucontext->uc_mcontext.arm_fp;
|
||||
*sp = ucontext->uc_mcontext.arm_sp;
|
||||
#elif defined(__aarch64__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.pc;
|
||||
*bp = ucontext->uc_mcontext.regs[29];
|
||||
*sp = ucontext->uc_mcontext.sp;
|
||||
#elif defined(__hppa__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.sc_iaoq[0];
|
||||
/* GCC uses %r3 whenever a frame pointer is needed. */
|
||||
*bp = ucontext->uc_mcontext.sc_gr[3];
|
||||
*sp = ucontext->uc_mcontext.sc_gr[30];
|
||||
#elif defined(__x86_64__)
|
||||
# if SANITIZER_FREEBSD
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.mc_rip;
|
||||
*bp = ucontext->uc_mcontext.mc_rbp;
|
||||
*sp = ucontext->uc_mcontext.mc_rsp;
|
||||
# else
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.gregs[REG_RIP];
|
||||
*bp = ucontext->uc_mcontext.gregs[REG_RBP];
|
||||
*sp = ucontext->uc_mcontext.gregs[REG_RSP];
|
||||
# endif
|
||||
#elif defined(__i386__)
|
||||
# if SANITIZER_FREEBSD
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.mc_eip;
|
||||
*bp = ucontext->uc_mcontext.mc_ebp;
|
||||
*sp = ucontext->uc_mcontext.mc_esp;
|
||||
# else
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.gregs[REG_EIP];
|
||||
*bp = ucontext->uc_mcontext.gregs[REG_EBP];
|
||||
*sp = ucontext->uc_mcontext.gregs[REG_ESP];
|
||||
# endif
|
||||
#elif defined(__powerpc__) || defined(__powerpc64__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.regs->nip;
|
||||
*sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
|
||||
// The powerpc{,64}-linux ABIs do not specify r31 as the frame
|
||||
// pointer, but GCC always uses r31 when we need a frame pointer.
|
||||
*bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
|
||||
#elif defined(__sparc__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
uptr *stk_ptr;
|
||||
# if defined (__arch64__)
|
||||
*pc = ucontext->uc_mcontext.mc_gregs[MC_PC];
|
||||
*sp = ucontext->uc_mcontext.mc_gregs[MC_O6];
|
||||
stk_ptr = (uptr *) (*sp + 2047);
|
||||
*bp = stk_ptr[15];
|
||||
# else
|
||||
*pc = ucontext->uc_mcontext.gregs[REG_PC];
|
||||
*sp = ucontext->uc_mcontext.gregs[REG_O6];
|
||||
stk_ptr = (uptr *) *sp;
|
||||
*bp = stk_ptr[15];
|
||||
# endif
|
||||
#elif defined(__mips__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.gregs[31];
|
||||
*bp = ucontext->uc_mcontext.gregs[30];
|
||||
*sp = ucontext->uc_mcontext.gregs[29];
|
||||
#else
|
||||
# error "Unsupported arch"
|
||||
#endif
|
||||
}
|
||||
|
||||
void AsanPlatformThreadInit() {
|
||||
// Nothing here for now.
|
||||
}
|
||||
|
|
|
@ -40,20 +40,6 @@
|
|||
|
||||
namespace __asan {
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
# if SANITIZER_WORDSIZE == 64
|
||||
*pc = ucontext->uc_mcontext->__ss.__rip;
|
||||
*bp = ucontext->uc_mcontext->__ss.__rbp;
|
||||
*sp = ucontext->uc_mcontext->__ss.__rsp;
|
||||
# else
|
||||
*pc = ucontext->uc_mcontext->__ss.__eip;
|
||||
*bp = ucontext->uc_mcontext->__ss.__ebp;
|
||||
*sp = ucontext->uc_mcontext->__ss.__esp;
|
||||
# endif // SANITIZER_WORDSIZE
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHasDifferentMemcpyAndMemmove() {
|
||||
// On OS X 10.7 memcpy() and memmove() are both resolved
|
||||
// into memmove$VARIANT$sse42.
|
||||
|
|
|
@ -32,13 +32,6 @@
|
|||
|
||||
namespace __asan {
|
||||
|
||||
SignalContext SignalContext::Create(void *siginfo, void *context) {
|
||||
uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;
|
||||
uptr pc, sp, bp;
|
||||
GetPcSpBp(context, &pc, &sp, &bp);
|
||||
return SignalContext(context, addr, pc, sp, bp);
|
||||
}
|
||||
|
||||
void AsanOnSIGSEGV(int, void *siginfo, void *context) {
|
||||
ScopedDeadlySignal signal_scope(GetCurrentThread());
|
||||
int code = (int)((siginfo_t*)siginfo)->si_code;
|
||||
|
|
|
@ -613,6 +613,23 @@ static inline void SanitizerBreakOptimization(void *arg) {
|
|||
#endif
|
||||
}
|
||||
|
||||
struct SignalContext {
|
||||
void *context;
|
||||
uptr addr;
|
||||
uptr pc;
|
||||
uptr sp;
|
||||
uptr bp;
|
||||
|
||||
SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp) :
|
||||
context(context), addr(addr), pc(pc), sp(sp), bp(bp) {
|
||||
}
|
||||
|
||||
// Creates signal context in a platform-specific manner.
|
||||
static SignalContext Create(void *siginfo, void *context);
|
||||
};
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
inline void *operator new(__sanitizer::operator_new_size_type size,
|
||||
|
|
|
@ -558,6 +558,7 @@ int internal_fork() {
|
|||
}
|
||||
|
||||
#if SANITIZER_LINUX
|
||||
#define SA_RESTORER 0x04000000
|
||||
// Doesn't set sa_restorer, use with caution (see below).
|
||||
int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
|
||||
__sanitizer_kernel_sigaction_t k_act, k_oldact;
|
||||
|
@ -570,7 +571,8 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
|
|||
k_act.sigaction = u_act->sigaction;
|
||||
internal_memcpy(&k_act.sa_mask, &u_act->sa_mask,
|
||||
sizeof(__sanitizer_kernel_sigset_t));
|
||||
k_act.sa_flags = u_act->sa_flags;
|
||||
// Without SA_RESTORER kernel ignores the calls (probably returns EINVAL).
|
||||
k_act.sa_flags = u_act->sa_flags | SA_RESTORER;
|
||||
// FIXME: most often sa_restorer is unset, however the kernel requires it
|
||||
// to point to a valid signal restorer that calls the rt_sigreturn syscall.
|
||||
// If sa_restorer passed to the kernel is NULL, the program may crash upon
|
||||
|
@ -928,6 +930,78 @@ void *internal_start_thread(void (*func)(void *), void *arg) { return 0; }
|
|||
void internal_join_thread(void *th) {}
|
||||
#endif
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
|
||||
#if defined(__arm__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.arm_pc;
|
||||
*bp = ucontext->uc_mcontext.arm_fp;
|
||||
*sp = ucontext->uc_mcontext.arm_sp;
|
||||
#elif defined(__aarch64__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.pc;
|
||||
*bp = ucontext->uc_mcontext.regs[29];
|
||||
*sp = ucontext->uc_mcontext.sp;
|
||||
#elif defined(__hppa__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.sc_iaoq[0];
|
||||
/* GCC uses %r3 whenever a frame pointer is needed. */
|
||||
*bp = ucontext->uc_mcontext.sc_gr[3];
|
||||
*sp = ucontext->uc_mcontext.sc_gr[30];
|
||||
#elif defined(__x86_64__)
|
||||
# if SANITIZER_FREEBSD
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.mc_rip;
|
||||
*bp = ucontext->uc_mcontext.mc_rbp;
|
||||
*sp = ucontext->uc_mcontext.mc_rsp;
|
||||
# else
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.gregs[REG_RIP];
|
||||
*bp = ucontext->uc_mcontext.gregs[REG_RBP];
|
||||
*sp = ucontext->uc_mcontext.gregs[REG_RSP];
|
||||
# endif
|
||||
#elif defined(__i386__)
|
||||
# if SANITIZER_FREEBSD
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.mc_eip;
|
||||
*bp = ucontext->uc_mcontext.mc_ebp;
|
||||
*sp = ucontext->uc_mcontext.mc_esp;
|
||||
# else
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.gregs[REG_EIP];
|
||||
*bp = ucontext->uc_mcontext.gregs[REG_EBP];
|
||||
*sp = ucontext->uc_mcontext.gregs[REG_ESP];
|
||||
# endif
|
||||
#elif defined(__powerpc__) || defined(__powerpc64__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.regs->nip;
|
||||
*sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
|
||||
// The powerpc{,64}-linux ABIs do not specify r31 as the frame
|
||||
// pointer, but GCC always uses r31 when we need a frame pointer.
|
||||
*bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
|
||||
#elif defined(__sparc__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
uptr *stk_ptr;
|
||||
# if defined (__arch64__)
|
||||
*pc = ucontext->uc_mcontext.mc_gregs[MC_PC];
|
||||
*sp = ucontext->uc_mcontext.mc_gregs[MC_O6];
|
||||
stk_ptr = (uptr *) (*sp + 2047);
|
||||
*bp = stk_ptr[15];
|
||||
# else
|
||||
*pc = ucontext->uc_mcontext.gregs[REG_PC];
|
||||
*sp = ucontext->uc_mcontext.gregs[REG_O6];
|
||||
stk_ptr = (uptr *) *sp;
|
||||
*bp = stk_ptr[15];
|
||||
# endif
|
||||
#elif defined(__mips__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
*pc = ucontext->uc_mcontext.gregs[31];
|
||||
*bp = ucontext->uc_mcontext.gregs[30];
|
||||
*sp = ucontext->uc_mcontext.gregs[29];
|
||||
#else
|
||||
# error "Unsupported arch"
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
|
||||
|
|
|
@ -345,6 +345,19 @@ uptr GetRSS() {
|
|||
void *internal_start_thread(void (*func)(void *arg), void *arg) { return 0; }
|
||||
void internal_join_thread(void *th) { }
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
# if SANITIZER_WORDSIZE == 64
|
||||
*pc = ucontext->uc_mcontext->__ss.__rip;
|
||||
*bp = ucontext->uc_mcontext->__ss.__rbp;
|
||||
*sp = ucontext->uc_mcontext->__ss.__rsp;
|
||||
# else
|
||||
*pc = ucontext->uc_mcontext->__ss.__eip;
|
||||
*bp = ucontext->uc_mcontext->__ss.__ebp;
|
||||
*sp = ucontext->uc_mcontext->__ss.__esp;
|
||||
# endif // SANITIZER_WORDSIZE
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_MAC
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "sanitizer_procmaps.h"
|
||||
#include "sanitizer_stacktrace.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#if SANITIZER_LINUX
|
||||
|
@ -327,6 +328,13 @@ bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SignalContext SignalContext::Create(void *siginfo, void *context) {
|
||||
uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;
|
||||
uptr pc, sp, bp;
|
||||
GetPcSpBp(context, &pc, &sp, &bp);
|
||||
return SignalContext(context, addr, pc, sp, bp);
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_POSIX
|
||||
|
|
|
@ -103,7 +103,7 @@ bool ThreadSuspender::SuspendThread(SuspendedThreadID tid) {
|
|||
VReport(1, "Could not attach to thread %d (errno %d).\n", tid, pterrno);
|
||||
return false;
|
||||
} else {
|
||||
VReport(1, "Attached to thread %d.\n", tid);
|
||||
VReport(2, "Attached to thread %d.\n", tid);
|
||||
// The thread is not guaranteed to stop before ptrace returns, so we must
|
||||
// wait on it. Note: if the thread receives a signal concurrently,
|
||||
// we can get notification about the signal before notification about stop.
|
||||
|
@ -143,7 +143,7 @@ void ThreadSuspender::ResumeAllThreads() {
|
|||
int pterrno;
|
||||
if (!internal_iserror(internal_ptrace(PTRACE_DETACH, tid, NULL, NULL),
|
||||
&pterrno)) {
|
||||
VReport(1, "Detached from thread %d.\n", tid);
|
||||
VReport(2, "Detached from thread %d.\n", tid);
|
||||
} else {
|
||||
// Either the thread is dead, or we are already detached.
|
||||
// The latter case is possible, for instance, if this function was called
|
||||
|
@ -202,7 +202,10 @@ struct TracerThreadArgument {
|
|||
static DieCallbackType old_die_callback;
|
||||
|
||||
// Signal handler to wake up suspended threads when the tracer thread dies.
|
||||
void TracerThreadSignalHandler(int signum, void *siginfo, void *) {
|
||||
void TracerThreadSignalHandler(int signum, void *siginfo, void *uctx) {
|
||||
SignalContext ctx = SignalContext::Create(siginfo, uctx);
|
||||
VPrintf(1, "Tracer caught signal %d: addr=0x%zx pc=0x%zx sp=0x%zx\n",
|
||||
signum, ctx.addr, ctx.pc, ctx.sp);
|
||||
if (thread_suspender_instance != NULL) {
|
||||
if (signum == SIGABRT)
|
||||
thread_suspender_instance->KillAllThreads();
|
||||
|
|
|
@ -189,6 +189,16 @@ TEST(StopTheWorld, SuspendThreadsAdvanced) {
|
|||
pthread_mutex_destroy(&advanced_incrementer_thread_exit_mutex);
|
||||
}
|
||||
|
||||
static void SegvCallback(const SuspendedThreadsList &suspended_threads_list,
|
||||
void *argument) {
|
||||
*(volatile int*)0x1234 = 0;
|
||||
}
|
||||
|
||||
TEST(StopTheWorld, SegvInCallback) {
|
||||
// Test that tracer thread catches SIGSEGV.
|
||||
StopTheWorld(&SegvCallback, NULL);
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_LINUX && defined(__x86_64__)
|
||||
|
|
|
@ -167,7 +167,7 @@ struct SignalDesc {
|
|||
ucontext_t ctx;
|
||||
};
|
||||
|
||||
struct SignalContext {
|
||||
struct ThreadSignalContext {
|
||||
int int_signal_send;
|
||||
atomic_uintptr_t in_blocking_func;
|
||||
atomic_uintptr_t have_pending_signals;
|
||||
|
@ -194,10 +194,10 @@ void InitializeLibIgnore() {
|
|||
|
||||
} // namespace __tsan
|
||||
|
||||
static SignalContext *SigCtx(ThreadState *thr) {
|
||||
SignalContext *ctx = (SignalContext*)thr->signal_ctx;
|
||||
static ThreadSignalContext *SigCtx(ThreadState *thr) {
|
||||
ThreadSignalContext *ctx = (ThreadSignalContext*)thr->signal_ctx;
|
||||
if (ctx == 0 && !thr->is_dead) {
|
||||
ctx = (SignalContext*)MmapOrDie(sizeof(*ctx), "SignalContext");
|
||||
ctx = (ThreadSignalContext*)MmapOrDie(sizeof(*ctx), "ThreadSignalContext");
|
||||
MemoryResetRange(thr, (uptr)&SigCtx, (uptr)ctx, sizeof(*ctx));
|
||||
thr->signal_ctx = ctx;
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ struct BlockingCall {
|
|||
}
|
||||
|
||||
ThreadState *thr;
|
||||
SignalContext *ctx;
|
||||
ThreadSignalContext *ctx;
|
||||
};
|
||||
|
||||
TSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) {
|
||||
|
@ -419,7 +419,7 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
|
|||
buf->sp = sp;
|
||||
buf->mangled_sp = mangled_sp;
|
||||
buf->shadow_stack_pos = thr->shadow_stack_pos;
|
||||
SignalContext *sctx = SigCtx(thr);
|
||||
ThreadSignalContext *sctx = SigCtx(thr);
|
||||
buf->int_signal_send = sctx ? sctx->int_signal_send : 0;
|
||||
buf->in_blocking_func = sctx ?
|
||||
atomic_load(&sctx->in_blocking_func, memory_order_relaxed) :
|
||||
|
@ -442,7 +442,7 @@ static void LongJmp(ThreadState *thr, uptr *env) {
|
|||
// Unwind the stack.
|
||||
while (thr->shadow_stack_pos > buf->shadow_stack_pos)
|
||||
FuncExit(thr);
|
||||
SignalContext *sctx = SigCtx(thr);
|
||||
ThreadSignalContext *sctx = SigCtx(thr);
|
||||
if (sctx) {
|
||||
sctx->int_signal_send = buf->int_signal_send;
|
||||
atomic_store(&sctx->in_blocking_func, buf->in_blocking_func,
|
||||
|
@ -878,7 +878,7 @@ static void thread_finalize(void *v) {
|
|||
{
|
||||
ThreadState *thr = cur_thread();
|
||||
ThreadFinish(thr);
|
||||
SignalContext *sctx = thr->signal_ctx;
|
||||
ThreadSignalContext *sctx = thr->signal_ctx;
|
||||
if (sctx) {
|
||||
thr->signal_ctx = 0;
|
||||
UnmapOrDie(sctx, sizeof(*sctx));
|
||||
|
@ -1940,7 +1940,7 @@ static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire,
|
|||
}
|
||||
|
||||
void ProcessPendingSignals(ThreadState *thr) {
|
||||
SignalContext *sctx = SigCtx(thr);
|
||||
ThreadSignalContext *sctx = SigCtx(thr);
|
||||
if (sctx == 0 ||
|
||||
atomic_load(&sctx->have_pending_signals, memory_order_relaxed) == 0)
|
||||
return;
|
||||
|
@ -1964,7 +1964,7 @@ void ProcessPendingSignals(ThreadState *thr) {
|
|||
|
||||
} // namespace __tsan
|
||||
|
||||
static bool is_sync_signal(SignalContext *sctx, int sig) {
|
||||
static bool is_sync_signal(ThreadSignalContext *sctx, int sig) {
|
||||
return sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
|
||||
sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || sig == SIGSYS ||
|
||||
// If we are sending signal to ourselves, we must process it now.
|
||||
|
@ -1974,7 +1974,7 @@ static bool is_sync_signal(SignalContext *sctx, int sig) {
|
|||
void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig,
|
||||
my_siginfo_t *info, void *ctx) {
|
||||
ThreadState *thr = cur_thread();
|
||||
SignalContext *sctx = SigCtx(thr);
|
||||
ThreadSignalContext *sctx = SigCtx(thr);
|
||||
if (sig < 0 || sig >= kSigCount) {
|
||||
VPrintf(1, "ThreadSanitizer: ignoring signal %d\n", sig);
|
||||
return;
|
||||
|
@ -2083,7 +2083,7 @@ TSAN_INTERCEPTOR(int, sigsuspend, const __sanitizer_sigset_t *mask) {
|
|||
|
||||
TSAN_INTERCEPTOR(int, raise, int sig) {
|
||||
SCOPED_TSAN_INTERCEPTOR(raise, sig);
|
||||
SignalContext *sctx = SigCtx(thr);
|
||||
ThreadSignalContext *sctx = SigCtx(thr);
|
||||
CHECK_NE(sctx, 0);
|
||||
int prev = sctx->int_signal_send;
|
||||
sctx->int_signal_send = sig;
|
||||
|
@ -2095,7 +2095,7 @@ TSAN_INTERCEPTOR(int, raise, int sig) {
|
|||
|
||||
TSAN_INTERCEPTOR(int, kill, int pid, int sig) {
|
||||
SCOPED_TSAN_INTERCEPTOR(kill, pid, sig);
|
||||
SignalContext *sctx = SigCtx(thr);
|
||||
ThreadSignalContext *sctx = SigCtx(thr);
|
||||
CHECK_NE(sctx, 0);
|
||||
int prev = sctx->int_signal_send;
|
||||
if (pid == (int)internal_getpid()) {
|
||||
|
@ -2111,7 +2111,7 @@ TSAN_INTERCEPTOR(int, kill, int pid, int sig) {
|
|||
|
||||
TSAN_INTERCEPTOR(int, pthread_kill, void *tid, int sig) {
|
||||
SCOPED_TSAN_INTERCEPTOR(pthread_kill, tid, sig);
|
||||
SignalContext *sctx = SigCtx(thr);
|
||||
ThreadSignalContext *sctx = SigCtx(thr);
|
||||
CHECK_NE(sctx, 0);
|
||||
int prev = sctx->int_signal_send;
|
||||
if (tid == pthread_self()) {
|
||||
|
|
|
@ -313,7 +313,7 @@ class Shadow : public FastState {
|
|||
}
|
||||
};
|
||||
|
||||
struct SignalContext;
|
||||
struct ThreadSignalContext;
|
||||
|
||||
struct JmpBuf {
|
||||
uptr sp;
|
||||
|
@ -387,7 +387,7 @@ struct ThreadState {
|
|||
DDLogicalThread *dd_lt;
|
||||
|
||||
atomic_uintptr_t in_signal_handler;
|
||||
SignalContext *signal_ctx;
|
||||
ThreadSignalContext *signal_ctx;
|
||||
|
||||
DenseSlabAllocCache block_cache;
|
||||
DenseSlabAllocCache sync_cache;
|
||||
|
|
Loading…
Reference in New Issue