[lsan] Deadly signal handler for lsan

Summary: Part of https://github.com/google/sanitizers/issues/637

Reviewers: eugenis, alekseyshl

Subscribers: llvm-commits, dberris, kubamracek, krytarowski

Differential Revision: https://reviews.llvm.org/D37608

llvm-svn: 314041
This commit is contained in:
Vitaly Buka 2017-09-22 22:57:48 +00:00
parent a33e156f81
commit 15d7e604d9
11 changed files with 47 additions and 10 deletions

View File

@ -65,6 +65,18 @@ static void InitializeFlags() {
if (common_flags()->help) parser.PrintFlagDescriptions();
}
static void OnStackUnwind(const SignalContext &sig, const void *,
BufferedStackTrace *stack) {
GetStackTraceWithPcBpAndContext(stack, kStackTraceMax, sig.pc, sig.bp,
sig.context,
common_flags()->fast_unwind_on_fatal);
}
void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
nullptr);
}
extern "C" void __lsan_init() {
CHECK(!lsan_init_is_running);
if (lsan_inited)
@ -80,6 +92,7 @@ extern "C" void __lsan_init() {
InitTlsSize();
InitializeInterceptors();
InitializeThreadRegistry();
InstallDeadlySignalHandlers(LsanOnDeadlySignal);
u32 tid = ThreadCreate(0, 0, true);
CHECK_EQ(tid, 0);
ThreadStart(tid, GetTid());

View File

@ -401,9 +401,14 @@ INTERCEPTOR(void, _exit, int status) {
REAL(_exit)(status);
}
#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
#include "sanitizer_common/sanitizer_signal_interceptors.inc"
namespace __lsan {
void InitializeInterceptors() {
InitializeSignalInterceptors();
INTERCEPT_FUNCTION(malloc);
INTERCEPT_FUNCTION(free);
LSAN_MAYBE_INTERCEPT_CFREE;

View File

@ -318,15 +318,24 @@ void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded));
typedef void (*SignalHandlerType)(int, void *, void *);
HandleSignalMode GetHandleSignalMode(int signum);
void InstallDeadlySignalHandlers(SignalHandlerType handler);
// Signal reporting.
void StartReportDeadlySignal();
// Each sanitizer uses slightly different implementation of stack unwinding.
typedef void (*UnwindSignalStackCallbackType)(const SignalContext &sig,
const void *callback_context,
BufferedStackTrace *stack);
// Print deadly signal report and die.
void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
UnwindSignalStackCallbackType unwind,
const void *unwind_context);
// Part of HandleDeadlySignal, exposed for asan.
void StartReportDeadlySignal();
// Part of HandleDeadlySignal, exposed for asan.
void ReportDeadlySignal(const SignalContext &sig, u32 tid,
UnwindSignalStackCallbackType unwind,
const void *unwind_context);
// Alternative signal stack (POSIX-only).
void SetAlternateSignalStack();
void UnsetAlternateSignalStack();

View File

@ -254,6 +254,18 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
else
ReportDeadlySignalImpl(sig, tid, unwind, unwind_context);
}
void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
UnwindSignalStackCallbackType unwind,
const void *unwind_context) {
StartReportDeadlySignal();
ScopedErrorReportLock rl;
SignalContext sig(siginfo, context);
ReportDeadlySignal(sig, tid, unwind, unwind_context);
Report("ABORTING\n");
Die();
}
#endif // !SANITIZER_FUCHSIA && !SANITIZER_GO
void WriteToSyslog(const char *msg) {

View File

@ -18,7 +18,6 @@
// clang-format on
// Remove when fixed: https://github.com/google/sanitizers/issues/637
// XFAIL: lsan
// XFAIL: msan
// XFAIL: tsan
// XFAIL: ubsan

View File

@ -7,11 +7,11 @@
// RUN: %env_tool_opts=handle_abort=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
// clang-format on
// FIXME: implement in other sanitizers, not just asan.
// FIXME: implement in other sanitizers.
// XFAIL: msan
// XFAIL: lsan
// XFAIL: tsan
// XFAIL: ubsan
#include <assert.h>
#include <stdio.h>
#include <sanitizer/asan_interface.h>

View File

@ -7,9 +7,8 @@
// RUN: %env_tool_opts=handle_sigill=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
// clang-format on
// FIXME: implement in other sanitizers, not just asan.
// FIXME: implement in other sanitizers.
// XFAIL: msan
// XFAIL: lsan
// XFAIL: tsan
// XFAIL: ubsan
//

View File

@ -9,7 +9,6 @@
// REQUIRES: stable-runtime
// FIXME: implement SEGV handler in other sanitizers, not just asan.
// XFAIL: msan
// XFAIL: lsan
// XFAIL: tsan
// XFAIL: ubsan

View File

@ -8,7 +8,10 @@
// clang-format on
// REQUIRES: x86-target-arch
// XFAIL: lsan, msan, tsan, ubsan
// FIXME: implement in other sanitizers.
// XFAIL: msan
// XFAIL: tsan
// XFAIL: ubsan
int main() {
#if defined(__x86_64__)

View File

@ -5,7 +5,6 @@
// RUN: %env_tool_opts=handle_sigfpe=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
// FIXME: implement in other sanitizers, not just asan.
// XFAIL: msan
// XFAIL: lsan
// XFAIL: tsan
// XFAIL: ubsan
//

View File

@ -8,7 +8,6 @@
// XFAIL: android && i386-target-arch && asan
// FIXME: implement SEGV handler in other sanitizers, not just asan.
// XFAIL: msan
// XFAIL: lsan
// XFAIL: tsan
// XFAIL: ubsan