[sanitizer] Move stack overflow and signal reporting from Asan into common.
Summary: Part of https://github.com/google/sanitizers/issues/637 Reviewers: eugenis, alekseyshl Subscribers: kubamracek Differential Revision: https://reviews.llvm.org/D37844 llvm-svn: 313310
This commit is contained in:
parent
846a217bfc
commit
21ddc6219b
|
@ -22,56 +22,21 @@
|
|||
|
||||
namespace __asan {
|
||||
|
||||
static void OnStackUnwind(const SignalContext &sig,
|
||||
const void *callback_context,
|
||||
BufferedStackTrace *stack) {
|
||||
// Tests and maybe some users expect that scariness is going to be printed
|
||||
// just before the stack. As only asan has scariness score we have no
|
||||
// corresponding code in the sanitizer_common and we use this callback to
|
||||
// print it.
|
||||
static_cast<const ScarinessScoreBase *>(callback_context)->Print();
|
||||
GetStackTraceWithPcBpAndContext(stack, kStackTraceMax, sig.pc, sig.bp,
|
||||
sig.context,
|
||||
common_flags()->fast_unwind_on_fatal);
|
||||
}
|
||||
|
||||
void ErrorDeadlySignal::Print() {
|
||||
if (signal.IsStackOverflow()) {
|
||||
Decorator d;
|
||||
Printf("%s", d.Warning());
|
||||
Report(
|
||||
"ERROR: AddressSanitizer: %s on address %p"
|
||||
" (pc %p bp %p sp %p T%d)\n",
|
||||
scariness.GetDescription(), (void *)signal.addr, (void *)signal.pc,
|
||||
(void *)signal.bp, (void *)signal.sp, tid);
|
||||
Printf("%s", d.Default());
|
||||
scariness.Print();
|
||||
BufferedStackTrace stack;
|
||||
GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, signal.pc,
|
||||
signal.bp, signal.context,
|
||||
common_flags()->fast_unwind_on_fatal);
|
||||
stack.Print();
|
||||
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||
} else {
|
||||
Decorator d;
|
||||
Printf("%s", d.Warning());
|
||||
const char *description = signal.Describe();
|
||||
Report(
|
||||
"ERROR: AddressSanitizer: %s on unknown address %p (pc %p bp %p sp %p "
|
||||
"T%d)\n",
|
||||
description, (void *)signal.addr, (void *)signal.pc, (void *)signal.bp,
|
||||
(void *)signal.sp, tid);
|
||||
Printf("%s", d.Default());
|
||||
if (signal.pc < GetPageSizeCached())
|
||||
Report("Hint: pc points to the zero page.\n");
|
||||
if (signal.is_memory_access) {
|
||||
const char *access_type =
|
||||
signal.write_flag == SignalContext::WRITE
|
||||
? "WRITE"
|
||||
: (signal.write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
|
||||
Report("The signal is caused by a %s memory access.\n", access_type);
|
||||
if (signal.addr < GetPageSizeCached())
|
||||
Report("Hint: address points to the zero page.\n");
|
||||
}
|
||||
MaybeReportNonExecRegion(signal.pc);
|
||||
scariness.Print();
|
||||
BufferedStackTrace stack;
|
||||
GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, signal.pc,
|
||||
signal.bp, signal.context,
|
||||
common_flags()->fast_unwind_on_fatal);
|
||||
stack.Print();
|
||||
MaybeDumpInstructionBytes(signal.pc);
|
||||
MaybeDumpRegisters(signal.context);
|
||||
Printf("AddressSanitizer can not provide additional info.\n");
|
||||
ReportErrorSummary(description, &stack);
|
||||
}
|
||||
ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness);
|
||||
}
|
||||
|
||||
void ErrorDoubleFree::Print() {
|
||||
|
|
|
@ -31,6 +31,7 @@ extern "C" void _ReadWriteBarrier();
|
|||
namespace __sanitizer {
|
||||
|
||||
struct AddressInfo;
|
||||
struct BufferedStackTrace;
|
||||
struct SignalContext;
|
||||
struct StackTrace;
|
||||
|
||||
|
@ -311,10 +312,13 @@ HandleSignalMode GetHandleSignalMode(int signum);
|
|||
void InstallDeadlySignalHandlers(SignalHandlerType handler);
|
||||
// Signal reporting.
|
||||
void StartReportDeadlySignal();
|
||||
// FIXME: Hide after moving more signal handling code into common.
|
||||
void MaybeReportNonExecRegion(uptr pc);
|
||||
void MaybeDumpInstructionBytes(uptr pc);
|
||||
void MaybeDumpRegisters(void *context);
|
||||
// Each sanitizer uses slightly different implementation of stack unwinding.
|
||||
typedef void (*UnwindSignalStackCallbackType)(const SignalContext &sig,
|
||||
const void *callback_context,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportDeadlySignal(const SignalContext &sig, u32 tid,
|
||||
UnwindSignalStackCallbackType unwind,
|
||||
const void *unwind_context);
|
||||
// Alternative signal stack (POSIX-only).
|
||||
void SetAlternateSignalStack();
|
||||
void UnsetAlternateSignalStack();
|
||||
|
|
|
@ -148,7 +148,7 @@ void BackgroundThread(void *arg) {
|
|||
#endif
|
||||
|
||||
#if !SANITIZER_GO
|
||||
void MaybeReportNonExecRegion(uptr pc) {
|
||||
static void MaybeReportNonExecRegion(uptr pc) {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
|
||||
MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
|
||||
MemoryMappedSegment segment;
|
||||
|
@ -166,7 +166,7 @@ static void PrintMemoryByte(InternalScopedString *str, const char *before,
|
|||
d.Default());
|
||||
}
|
||||
|
||||
void MaybeDumpInstructionBytes(uptr pc) {
|
||||
static void MaybeDumpInstructionBytes(uptr pc) {
|
||||
if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
|
||||
return;
|
||||
InternalScopedString str(1024);
|
||||
|
@ -182,11 +182,71 @@ void MaybeDumpInstructionBytes(uptr pc) {
|
|||
Report("%s", str.data());
|
||||
}
|
||||
|
||||
void MaybeDumpRegisters(void *context) {
|
||||
static void MaybeDumpRegisters(void *context) {
|
||||
if (!common_flags()->dump_registers) return;
|
||||
SignalContext::DumpAllRegisters(context);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ReportStackOverflowImpl(const SignalContext &sig, u32 tid,
|
||||
UnwindSignalStackCallbackType unwind,
|
||||
const void *unwind_context) {
|
||||
SanitizerCommonDecorator d;
|
||||
Printf("%s", d.Warning());
|
||||
static const char kDescription[] = "stack-overflow";
|
||||
Report("ERROR: %s: %s on address %p (pc %p bp %p sp %p T%d)\n",
|
||||
SanitizerToolName, kDescription, (void *)sig.addr, (void *)sig.pc,
|
||||
(void *)sig.bp, (void *)sig.sp, tid);
|
||||
Printf("%s", d.Default());
|
||||
InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
|
||||
BufferedStackTrace *stack = stack_buffer.data();
|
||||
stack->Reset();
|
||||
unwind(sig, unwind_context, stack);
|
||||
stack->Print();
|
||||
ReportErrorSummary(kDescription, stack);
|
||||
}
|
||||
|
||||
static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid,
|
||||
UnwindSignalStackCallbackType unwind,
|
||||
const void *unwind_context) {
|
||||
SanitizerCommonDecorator d;
|
||||
Printf("%s", d.Warning());
|
||||
const char *description = sig.Describe();
|
||||
Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n",
|
||||
SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc,
|
||||
(void *)sig.bp, (void *)sig.sp, tid);
|
||||
Printf("%s", d.Default());
|
||||
if (sig.pc < GetPageSizeCached())
|
||||
Report("Hint: pc points to the zero page.\n");
|
||||
if (sig.is_memory_access) {
|
||||
const char *access_type =
|
||||
sig.write_flag == SignalContext::WRITE
|
||||
? "WRITE"
|
||||
: (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
|
||||
Report("The signal is caused by a %s memory access.\n", access_type);
|
||||
if (sig.addr < GetPageSizeCached())
|
||||
Report("Hint: address points to the zero page.\n");
|
||||
}
|
||||
MaybeReportNonExecRegion(sig.pc);
|
||||
InternalScopedBuffer<BufferedStackTrace> stack_buffer(1);
|
||||
BufferedStackTrace *stack = stack_buffer.data();
|
||||
stack->Reset();
|
||||
unwind(sig, unwind_context, stack);
|
||||
stack->Print();
|
||||
MaybeDumpInstructionBytes(sig.pc);
|
||||
MaybeDumpRegisters(sig.context);
|
||||
Printf("%s can not provide additional info.\n", SanitizerToolName);
|
||||
ReportErrorSummary(description, stack);
|
||||
}
|
||||
|
||||
void ReportDeadlySignal(const SignalContext &sig, u32 tid,
|
||||
UnwindSignalStackCallbackType unwind,
|
||||
const void *unwind_context) {
|
||||
if (sig.IsStackOverflow())
|
||||
ReportStackOverflowImpl(sig, tid, unwind, unwind_context);
|
||||
else
|
||||
ReportDeadlySignalImpl(sig, tid, unwind, unwind_context);
|
||||
}
|
||||
#endif // !SANITIZER_GO
|
||||
|
||||
void WriteToSyslog(const char *msg) {
|
||||
InternalScopedString msg_copy(kErrorMessageBufferSize);
|
||||
|
|
|
@ -92,6 +92,9 @@ void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {}
|
|||
void DisableCoreDumperIfNecessary() {}
|
||||
void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
|
||||
void StartReportDeadlySignal() {}
|
||||
void ReportDeadlySignal(const SignalContext &sig, u32 tid,
|
||||
UnwindSignalStackCallbackType unwind,
|
||||
const void *unwind_context) {}
|
||||
void SetAlternateSignalStack() {}
|
||||
void UnsetAlternateSignalStack() {}
|
||||
void InitTlsSize() {}
|
||||
|
|
Loading…
Reference in New Issue