[sanitizer] Move IsStackOverflow into SignalContext

llvm-svn: 313227
This commit is contained in:
Vitaly Buka 2017-09-14 03:23:02 +00:00
parent 5d53e050ca
commit 9a4c73e20c
5 changed files with 15 additions and 9 deletions

View File

@ -37,7 +37,7 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
ScopedDeadlySignal signal_scope(GetCurrentThread()); ScopedDeadlySignal signal_scope(GetCurrentThread());
StartReportDeadlySignal(); StartReportDeadlySignal();
SignalContext sig(siginfo, context); SignalContext sig(siginfo, context);
if (IsStackOverflow(sig)) if (sig.IsStackOverflow())
ReportStackOverflow(sig); ReportStackOverflow(sig);
else else
ReportDeadlySignal(sig); ReportDeadlySignal(sig);

View File

@ -311,7 +311,6 @@ HandleSignalMode GetHandleSignalMode(int signum);
void InstallDeadlySignalHandlers(SignalHandlerType handler); void InstallDeadlySignalHandlers(SignalHandlerType handler);
// Signal reporting. // Signal reporting.
void StartReportDeadlySignal(); void StartReportDeadlySignal();
bool IsStackOverflow(const SignalContext &sig);
// FIXME: Hide after moving more signal handling code into common. // FIXME: Hide after moving more signal handling code into common.
void MaybeReportNonExecRegion(uptr pc); void MaybeReportNonExecRegion(uptr pc);
void MaybeDumpInstructionBytes(uptr pc); void MaybeDumpInstructionBytes(uptr pc);
@ -827,6 +826,9 @@ struct SignalContext {
// String description of the signal. // String description of the signal.
const char *Describe() const; const char *Describe() const;
// Returns true if signal is stack overflow.
bool IsStackOverflow() const;
private: private:
// Platform specific initialization. // Platform specific initialization.
void InitPcSpBp(); void InitPcSpBp();

View File

@ -97,6 +97,7 @@ void InitTlsSize() {}
void PrintModuleMap() {} void PrintModuleMap() {}
bool SignalContext::IsStackOverflow() const { return false; }
void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); } void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); }
const char *SignalContext::Describe() const { UNIMPLEMENTED(); } const char *SignalContext::Describe() const { UNIMPLEMENTED(); }

View File

@ -215,7 +215,7 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) {
MaybeInstallSigaction(SIGILL, handler); MaybeInstallSigaction(SIGILL, handler);
} }
bool IsStackOverflow(const SignalContext &sig) { bool SignalContext::IsStackOverflow() const {
// Access at a reasonable offset above SP, or slightly below it (to account // 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 // for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is
// probably a stack overflow. // probably a stack overflow.
@ -223,10 +223,9 @@ bool IsStackOverflow(const SignalContext &sig) {
// On s390, the fault address in siginfo points to start of the page, not // On s390, the fault address in siginfo points to start of the page, not
// to the precise word that was accessed. Mask off the low bits of sp to // to the precise word that was accessed. Mask off the low bits of sp to
// take it into account. // take it into account.
bool IsStackAccess = bool IsStackAccess = sig.addr >= (sig.sp & ~0xFFF) && sig.addr < sp + 0xFFFF;
sig.addr >= (sig.sp & ~0xFFF) && sig.addr < sig.sp + 0xFFFF;
#else #else
bool IsStackAccess = sig.addr + 512 > sig.sp && sig.addr < sig.sp + 0xFFFF; bool IsStackAccess = addr + 512 > sp && addr < sp + 0xFFFF;
#endif #endif
#if __powerpc__ #if __powerpc__
@ -236,8 +235,8 @@ bool IsStackOverflow(const SignalContext &sig) {
// If the store faults then sp will not have been updated, so test above // If the store faults then sp will not have been updated, so test above
// will not work, because the fault address will be more than just "slightly" // will not work, because the fault address will be more than just "slightly"
// below sp. // below sp.
if (!IsStackAccess && IsAccessibleMemoryRange(sig.pc, 4)) { if (!IsStackAccess && IsAccessibleMemoryRange(pc, 4)) {
u32 inst = *(unsigned *)sig.pc; u32 inst = *(unsigned *)pc;
u32 ra = (inst >> 16) & 0x1F; u32 ra = (inst >> 16) & 0x1F;
u32 opcd = inst >> 26; u32 opcd = inst >> 26;
u32 xo = (inst >> 1) & 0x3FF; u32 xo = (inst >> 1) & 0x3FF;
@ -257,7 +256,7 @@ bool IsStackOverflow(const SignalContext &sig) {
// We also check si_code to filter out SEGV caused by something else other // 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, // then hitting the guard page or unmapped memory, like, for example,
// unaligned memory access. // unaligned memory access.
auto si = static_cast<const siginfo_t *>(sig.siginfo); auto si = static_cast<const siginfo_t *>(siginfo);
return IsStackAccess && return IsStackAccess &&
(si->si_code == si_SEGV_MAPERR || si->si_code == si_SEGV_ACCERR); (si->si_code == si_SEGV_MAPERR || si->si_code == si_SEGV_ACCERR);
} }

View File

@ -915,6 +915,10 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) {
return true; return true;
} }
bool SignalContext::IsStackOverflow() const {
return GetType() == EXCEPTION_STACK_OVERFLOW;
}
void SignalContext::InitPcSpBp() { void SignalContext::InitPcSpBp() {
EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo; EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
CONTEXT *context_record = (CONTEXT *)context; CONTEXT *context_record = (CONTEXT *)context;