summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2017-09-13 18:30:06 +0000
committerVitaly Buka <vitalybuka@google.com>2017-09-13 18:30:06 +0000
commit2eaff6eec07f4e8ac7698bde99cd91ef01b7a0b1 (patch)
treed3b817edef564ee736e898d67b889c0211dad97f /lib
parent5c8c2c47d086e5881ccda48a66b5b09eb938237c (diff)
[compiler-rt] Add siginfo into SignalContext
Summary: Information stored there is often been passed along with SignalContext. Part of https://github.com/google/sanitizers/issues/637 Reviewers: eugenis, alekseyshl Subscribers: kubamracek, llvm-commits, dberris Differential Revision: https://reviews.llvm.org/D37792 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@313167 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/asan/asan_errors.h4
-rw-r--r--lib/asan/asan_posix.cc4
-rw-r--r--lib/asan/asan_report.cc4
-rw-r--r--lib/asan/asan_report.h2
-rw-r--r--lib/sanitizer_common/sanitizer_common.h18
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc9
-rw-r--r--lib/sanitizer_common/sanitizer_posix_libcdep.cc6
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc8
8 files changed, 38 insertions, 17 deletions
diff --git a/lib/asan/asan_errors.h b/lib/asan/asan_errors.h
index 9a1249244..55b8360a3 100644
--- a/lib/asan/asan_errors.h
+++ b/lib/asan/asan_errors.h
@@ -57,14 +57,14 @@ struct ErrorDeadlySignal : ErrorBase {
// VS2013 doesn't implement unrestricted unions, so we need a trivial default
// constructor
ErrorDeadlySignal() = default;
- ErrorDeadlySignal(u32 tid, const SignalContext &sig, int signo_)
+ ErrorDeadlySignal(u32 tid, const SignalContext &sig)
: ErrorBase(tid),
addr(sig.addr),
pc(sig.pc),
bp(sig.bp),
sp(sig.sp),
context(sig.context),
- signo(signo_),
+ signo(sig.GetType()),
write_flag(sig.write_flag),
is_memory_access(sig.is_memory_access) {
scariness.Clear();
diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc
index 8f788bd13..497af02d7 100644
--- a/lib/asan/asan_posix.cc
+++ b/lib/asan/asan_posix.cc
@@ -37,10 +37,10 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
ScopedDeadlySignal signal_scope(GetCurrentThread());
StartReportDeadlySignal();
SignalContext sig = SignalContext::Create(siginfo, context);
- if (IsStackOverflow(((siginfo_t *)siginfo)->si_code, sig))
+ if (IsStackOverflow(sig))
ReportStackOverflow(sig);
else
- ReportDeadlySignal(signo, sig);
+ ReportDeadlySignal(sig);
}
// ---------------------- TSD ---------------- {{{1
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 312dcaeae..6055304e8 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -266,9 +266,9 @@ void ReportStackOverflow(const SignalContext &sig) {
in_report.ReportError(error);
}
-void ReportDeadlySignal(int signo, const SignalContext &sig) {
+void ReportDeadlySignal(const SignalContext &sig) {
ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorDeadlySignal error(GetCurrentTidOrInvalid(), sig, signo);
+ ErrorDeadlySignal error(GetCurrentTidOrInvalid(), sig);
in_report.ReportError(error);
}
diff --git a/lib/asan/asan_report.h b/lib/asan/asan_report.h
index 5a3533a31..259177bc7 100644
--- a/lib/asan/asan_report.h
+++ b/lib/asan/asan_report.h
@@ -47,7 +47,7 @@ bool ParseFrameDescription(const char *frame_descr,
void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
uptr access_size, u32 exp, bool fatal);
void ReportStackOverflow(const SignalContext &sig);
-void ReportDeadlySignal(int signo, const SignalContext &sig);
+void ReportDeadlySignal(const SignalContext &sig);
void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
BufferedStackTrace *free_stack);
void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index d2021a0c9..32fd381cc 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -312,7 +312,7 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler);
const char *DescribeSignalOrException(int signo);
// Signal reporting.
void StartReportDeadlySignal();
-bool IsStackOverflow(int code, const SignalContext &sig);
+bool IsStackOverflow(const SignalContext &sig);
// FIXME: Hide after moving more signal handling code into common.
void MaybeReportNonExecRegion(uptr pc);
void MaybeDumpInstructionBytes(uptr pc);
@@ -795,6 +795,7 @@ static inline void SanitizerBreakOptimization(void *arg) {
}
struct SignalContext {
+ void *siginfo;
void *context;
uptr addr;
uptr pc;
@@ -804,9 +805,12 @@ struct SignalContext {
enum WriteFlag { UNKNOWN, READ, WRITE } write_flag;
- SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp,
- bool is_memory_access, WriteFlag write_flag)
- : context(context),
+ // SignalContext is going to keep pointers to siginfo and context without
+ // owning them.
+ SignalContext(void *siginfo, void *context, uptr addr, uptr pc, uptr sp,
+ uptr bp, bool is_memory_access, WriteFlag write_flag)
+ : siginfo(siginfo),
+ context(context),
addr(addr),
pc(pc),
sp(sp),
@@ -821,6 +825,12 @@ struct SignalContext {
// Returns true if the "context" indicates a memory write.
static WriteFlag GetWriteFlag(void *context);
+
+ // Type of signal e.g. SIGSEGV or EXCEPTION_ACCESS_VIOLATION.
+ int GetType() const;
+
+ // String description of the signal.
+ const char *Describe() const { return DescribeSignalOrException(GetType()); }
};
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index b8f4575f7..b74b1f995 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -296,13 +296,18 @@ bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
}
SignalContext SignalContext::Create(void *siginfo, void *context) {
- auto si = (siginfo_t *)siginfo;
+ auto si = static_cast<const siginfo_t *>(siginfo);
uptr addr = (uptr)si->si_addr;
uptr pc, sp, bp;
GetPcSpBp(context, &pc, &sp, &bp);
WriteFlag write_flag = GetWriteFlag(context);
bool is_memory_access = si->si_signo == SIGSEGV;
- return SignalContext(context, addr, pc, sp, bp, is_memory_access, write_flag);
+ return SignalContext(siginfo, context, addr, pc, sp, bp, is_memory_access,
+ write_flag);
+}
+
+int SignalContext::GetType() const {
+ return static_cast<const siginfo_t *>(siginfo)->si_signo;
}
const char *DescribeSignalOrException(int signo) {
diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index d7d0e7d44..e49101a7b 100644
--- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -215,7 +215,7 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) {
MaybeInstallSigaction(SIGILL, handler);
}
-bool IsStackOverflow(int code, const SignalContext &sig) {
+bool IsStackOverflow(const SignalContext &sig) {
// Access at a reasonable offset above SP, or slightly below it (to account
// for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is
// probably a stack overflow.
@@ -257,7 +257,9 @@ bool IsStackOverflow(int code, const SignalContext &sig) {
// We also check si_code to filter out SEGV caused by something else other
// then hitting the guard page or unmapped memory, like, for example,
// unaligned memory access.
- return IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR);
+ auto si = static_cast<const siginfo_t *>(sig.siginfo);
+ return IsStackAccess &&
+ (si->si_code == si_SEGV_MAPERR || si->si_code == si_SEGV_ACCERR);
}
void StartReportDeadlySignal() {
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index a13a4c5a5..65898a709 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -966,14 +966,18 @@ SignalContext SignalContext::Create(void *siginfo, void *context) {
case 8: write_flag = SignalContext::UNKNOWN; break;
}
bool is_memory_access = write_flag != SignalContext::UNKNOWN;
- return SignalContext(context, access_addr, pc, sp, bp, is_memory_access,
- write_flag);
+ return SignalContext(siginfo, context, access_addr, pc, sp, bp,
+ is_memory_access, write_flag);
}
void SignalContext::DumpAllRegisters(void *context) {
// FIXME: Implement this.
}
+int SignalContext::GetType() const {
+ return static_cast<const EXCEPTION_RECORD *>(siginfo)->ExceptionCode;
+}
+
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
// FIXME: Actually implement this function.
CHECK_GT(buf_len, 0);