Skip to content
This repository has been archived by the owner on May 21, 2019. It is now read-only.

Commit

Permalink
[ASan] Move the SIGSEGV/SIGBUS handling to sanitizer_common
Browse files Browse the repository at this point in the history
This change is a part of refactoring intended to have common signal handling behavior in all tools.
This particular CL moves InstallSignalHandlers() into sanitizer_common (making it InstallDeadlySignalHandlers()), but doesn't enable default signal handlers for any tool other than ASan.



git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@200542 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
ramosian-glider committed Jan 31, 2014
1 parent 7c8ecc2 commit 4c26afd
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 31 deletions.
7 changes: 7 additions & 0 deletions lib/asan/asan_interceptors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
}
return 0;
}

extern "C"
int __sanitizer_sigaction_f(int signum, const void *act, void *oldact) {
return REAL(sigaction)(signum,
(struct sigaction *)act, (struct sigaction *)oldact);
}

#elif SANITIZER_POSIX
// We need to have defined REAL(sigaction) on posix systems.
DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
Expand Down
2 changes: 1 addition & 1 deletion lib/asan/asan_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ void ReplaceSystemMalloc();
void *AsanDoesNotSupportStaticLinkage();

void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
void AsanOnSIGSEGV(int, void *siginfo, void *context);

void MaybeReexec();
bool AsanInterceptsSignal(int signum);
void InstallSignalHandlers();
void ReadContextStack(void *context, uptr *stack, uptr *ssize);
void AsanPlatformThreadInit();
void StopInitOrderChecking();
Expand Down
26 changes: 2 additions & 24 deletions lib/asan/asan_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +32,15 @@

namespace __asan {

static void MaybeInstallSigaction(int signum,
void (*handler)(int, siginfo_t *, void *)) {
if (!AsanInterceptsSignal(signum))
return;
struct sigaction sigact;
REAL(memset)(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction = handler;
sigact.sa_flags = SA_SIGINFO;
if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
CHECK_EQ(0, REAL(sigaction)(signum, &sigact, 0));
VReport(1, "Installed the sigaction for signal %d\n", signum);
}

static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) {
uptr addr = (uptr)siginfo->si_addr;
void AsanOnSIGSEGV(int, void *siginfo, void *context) {
uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;
// Write the first message using the bullet-proof write.
if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
uptr pc, sp, bp;
GetPcSpBp(context, &pc, &sp, &bp);
ReportSIGSEGV(pc, sp, bp, addr);
}

void InstallSignalHandlers() {
// Set the alternate signal stack for the main thread.
// This will cause SetAlternateSignalStack to be called twice, but the stack
// will be actually set only once.
if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
MaybeInstallSigaction(SIGSEGV, ASAN_OnSIGSEGV);
MaybeInstallSigaction(SIGBUS, ASAN_OnSIGSEGV);
}

// ---------------------- TSD ---------------- {{{1

static pthread_key_t tsd_key;
Expand Down
2 changes: 1 addition & 1 deletion lib/asan/asan_rtl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ static void AsanInitInternal() {
}

AsanTSDInit(PlatformTSDDtor);
InstallSignalHandlers();
InstallDeadlySignalHandlers(AsanOnSIGSEGV);

// Allocator should be initialized before starting external symbolizer, as
// fork() on Mac locks the allocator.
Expand Down
4 changes: 0 additions & 4 deletions lib/asan/asan_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@ void *AsanDoesNotSupportStaticLinkage() {
return 0;
}

void InstallSignalHandlers() {
// FIXME: Decide what to do on Windows.
}

void AsanPlatformThreadInit() {
// Nothing here for now.
}
Expand Down
4 changes: 4 additions & 0 deletions lib/sanitizer_common/sanitizer_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
void SetCheckFailedCallback(CheckFailedCallbackType callback);

// Functions related to signal handling.
typedef void (*SignalHandlerType)(int, void *, void *);
bool IsDeadlySignal(int signum);
void InstallDeadlySignalHandlers(SignalHandlerType handler);
// Alternative signal stack (POSIX-only).
void SetAlternateSignalStack();
void UnsetAlternateSignalStack();

Expand Down
2 changes: 2 additions & 0 deletions lib/sanitizer_common/sanitizer_libc.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ uptr internal_sched_yield();
// Error handling
bool internal_iserror(uptr retval, int *rverrno = 0);

int internal_sigaction(int signum, const void *act, void *oldact);

} // namespace __sanitizer

#endif // SANITIZER_LIBC_H
5 changes: 5 additions & 0 deletions lib/sanitizer_common/sanitizer_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#if SANITIZER_LINUX

#include "sanitizer_common.h"
#include "sanitizer_flags.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_linux.h"
Expand Down Expand Up @@ -698,6 +699,10 @@ void AndroidLogWrite(const char *buffer) {
}
#endif

bool IsDeadlySignal(int signum) {
return (signum == SIGSEGV) && common_flags()->handle_segv;
}

} // namespace __sanitizer

#endif // SANITIZER_LINUX
11 changes: 10 additions & 1 deletion lib/sanitizer_common/sanitizer_linux_libcdep.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <dlfcn.h>
#include <pthread.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <unwind.h>
Expand All @@ -39,7 +40,6 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE int
__sanitizer_pthread_attr_getstack(void *attr, void **addr, size_t *size);

static int my_pthread_attr_getstack(void *attr, void **addr, size_t *size) {
#
if (__sanitizer_pthread_attr_getstack)
return __sanitizer_pthread_attr_getstack((pthread_attr_t *)attr, addr,
size);
Expand All @@ -50,6 +50,15 @@ static int my_pthread_attr_getstack(void *attr, void **addr, size_t *size) {

namespace __sanitizer {

extern "C" SANITIZER_WEAK_ATTRIBUTE int
__sanitizer_sigaction_f(int signum, const void *act, void *oldact);

int internal_sigaction(int signum, const void *act, void *oldact) {
if (__sanitizer_sigaction_f)
return __sanitizer_sigaction_f(signum, act, oldact);
return sigaction(signum, (struct sigaction *)act, (struct sigaction *)oldact);
}

#ifndef SANITIZER_GO
void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
uptr *stack_bottom) {
Expand Down
11 changes: 11 additions & 0 deletions lib/sanitizer_common/sanitizer_mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <stdio.h>

#include "sanitizer_common.h"
#include "sanitizer_flags.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_placement_new.h"
Expand All @@ -32,6 +33,7 @@
#include <fcntl.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -118,6 +120,11 @@ uptr internal_getpid() {
return getpid();
}

int internal_sigaction(int signum, const void *act, void *oldact) {
return sigaction(signum,
(struct sigaction *)act, (struct sigaction *)oldact);
}

// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
struct stat st;
Expand Down Expand Up @@ -238,6 +245,10 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
return memory_mapping.DumpListOfModules(modules, max_modules, filter);
}

bool IsDeadlySignal(int signum) {
return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
}

} // namespace __sanitizer

#endif // SANITIZER_MAC
25 changes: 25 additions & 0 deletions lib/sanitizer_common/sanitizer_posix_libcdep.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#if SANITIZER_LINUX || SANITIZER_MAC
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
#include "sanitizer_platform_limits_posix.h"
#include "sanitizer_stacktrace.h"

#include <errno.h>
Expand Down Expand Up @@ -117,6 +119,29 @@ void UnsetAlternateSignalStack() {
UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
}

typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
static void MaybeInstallSigaction(int signum,
SignalHandlerType handler) {
if (!IsDeadlySignal(signum))
return;
struct sigaction sigact;
internal_memset(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction = (sa_sigaction_t)handler;
sigact.sa_flags = SA_SIGINFO;
if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
CHECK_EQ(0, internal_sigaction(signum, &sigact, 0));
VReport(1, "Installed the sigaction for signal %d\n", signum);
}

void InstallDeadlySignalHandlers(SignalHandlerType handler) {
// Set the alternate signal stack for the main thread.
// This will cause SetAlternateSignalStack to be called twice, but the stack
// will be actually set only once.
if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
MaybeInstallSigaction(SIGSEGV, handler);
MaybeInstallSigaction(SIGBUS, handler);
}

} // namespace __sanitizer

#endif
9 changes: 9 additions & 0 deletions lib/sanitizer_common/sanitizer_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,15 @@ void UnsetAlternateSignalStack() {
// FIXME: Decide what to do on Windows.
}

void InstallDeadlySignalHandlers() {
// FIXME: Decide what to do on Windows.
}

bool IsDeadlySignal(int signum) {
// FIXME: Decide what to do on Windows.
return false;
}

} // namespace __sanitizer

#endif // _WIN32

0 comments on commit 4c26afd

Please sign in to comment.