mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:26:45 +00:00
[asan] When catching a signal caused by a memory access, print if it's a READ or a WRITE. This touches win/mac files which I have not tested, if a win/mac bot fails I'll try to quick-fix
llvm-svn: 259741
This commit is contained in:
parent
155402c9c2
commit
2b9be25066
@ -761,10 +761,15 @@ void ReportDeadlySignal(const char *description, const SignalContext &sig) {
|
||||
" (pc %p bp %p sp %p T%d)\n",
|
||||
description, (void *)sig.addr, (void *)sig.pc, (void *)sig.bp,
|
||||
(void *)sig.sp, GetCurrentTidOrInvalid());
|
||||
if (sig.pc < GetPageSizeCached()) {
|
||||
Report("Hint: pc points to the zero page.\n");
|
||||
}
|
||||
Printf("%s", d.EndWarning());
|
||||
if (sig.pc < GetPageSizeCached())
|
||||
Report("Hint: pc points to the zero page.\n");
|
||||
if (sig.is_memory_access) {
|
||||
Report("The signal is caused by a %s memory access.\n",
|
||||
sig.is_write ? "WRITE" : "READ");
|
||||
if (sig.addr < GetPageSizeCached())
|
||||
Report("Hint: address points to the zero page.\n");
|
||||
}
|
||||
GET_STACK_TRACE_SIGNAL(sig);
|
||||
stack.Print();
|
||||
MaybeDumpInstructionBytes(sig.pc);
|
||||
|
@ -749,15 +749,20 @@ struct SignalContext {
|
||||
uptr pc;
|
||||
uptr sp;
|
||||
uptr bp;
|
||||
bool is_memory_access;
|
||||
bool is_write;
|
||||
|
||||
SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp) :
|
||||
context(context), addr(addr), pc(pc), sp(sp), bp(bp) {
|
||||
}
|
||||
SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp,
|
||||
bool is_memory_access, bool is_write)
|
||||
: context(context), addr(addr), pc(pc), sp(sp), bp(bp),
|
||||
is_memory_access(is_memory_access), is_write(is_write) {}
|
||||
|
||||
// Creates signal context in a platform-specific manner.
|
||||
static SignalContext Create(void *siginfo, void *context);
|
||||
};
|
||||
|
||||
// Returns true if the "context" indicates a memory write.
|
||||
bool GetSigContextWriteFlag(void *context);
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
|
||||
|
||||
void DisableReexec();
|
||||
|
@ -1155,6 +1155,11 @@ void *internal_start_thread(void (*func)(void *), void *arg) { return 0; }
|
||||
void internal_join_thread(void *th) {}
|
||||
#endif
|
||||
|
||||
bool GetSigContextWriteFlag(void *context) {
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
return ucontext->uc_mcontext.gregs[REG_ERR] & 2;
|
||||
}
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
|
||||
#if defined(__arm__)
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
|
@ -491,6 +491,10 @@ void LogFullErrorReport(const char *buffer) {
|
||||
// The report is added to CrashLog as part of logging all of Printf output.
|
||||
}
|
||||
|
||||
bool GetSigContextWriteFlag(void *context) {
|
||||
return false; // FIXME: implement this.
|
||||
}
|
||||
|
||||
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
|
||||
ucontext_t *ucontext = (ucontext_t*)context;
|
||||
# if defined(__aarch64__)
|
||||
|
@ -323,10 +323,13 @@ bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
|
||||
}
|
||||
|
||||
SignalContext SignalContext::Create(void *siginfo, void *context) {
|
||||
uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;
|
||||
auto si = (siginfo_t*)siginfo;
|
||||
uptr addr = (uptr)si->si_addr;
|
||||
uptr pc, sp, bp;
|
||||
GetPcSpBp(context, &pc, &sp, &bp);
|
||||
return SignalContext(context, addr, pc, sp, bp);
|
||||
bool is_write = GetSigContextWriteFlag(context);
|
||||
bool is_memory_access = si->si_signo == SIGSEGV;
|
||||
return SignalContext(context, addr, pc, sp, bp, is_memory_access, is_write);
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
@ -744,7 +744,10 @@ SignalContext SignalContext::Create(void *siginfo, void *context) {
|
||||
#endif
|
||||
uptr access_addr = exception_record->ExceptionInformation[1];
|
||||
|
||||
return SignalContext(context, access_addr, pc, sp, bp);
|
||||
bool is_write = false; // FIXME: compute this.
|
||||
bool is_memory_access = false; // FIXME: compute this.
|
||||
return SignalContext(context, access_addr, pc, sp, bp, is_memory_access,
|
||||
is_write);
|
||||
}
|
||||
|
||||
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
|
||||
|
17
compiler-rt/test/asan/TestCases/Linux/segv_read_write.c
Normal file
17
compiler-rt/test/asan/TestCases/Linux/segv_read_write.c
Normal file
@ -0,0 +1,17 @@
|
||||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ
|
||||
// RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE
|
||||
|
||||
static volatile int sink;
|
||||
__attribute__((noinline)) void Read(int *ptr) { sink = *ptr; }
|
||||
__attribute__((noinline)) void Write(int *ptr) { *ptr = 0; }
|
||||
int main(int argc, char **argv) {
|
||||
if (argc == 1)
|
||||
Read((int *)0);
|
||||
else
|
||||
Write((int *)0);
|
||||
}
|
||||
// READ: AddressSanitizer: SEGV on unknown address
|
||||
// READ: The signal is caused by a READ memory access.
|
||||
// WRITE: AddressSanitizer: SEGV on unknown address
|
||||
// WRITE: The signal is caused by a WRITE memory access.
|
Loading…
x
Reference in New Issue
Block a user