[compiler-rt] r218243 - [ASan] Introduce the dump_instruction_bytes flag to print the faulting instruction upon SIGSEGV
Alexander Potapenko
glider at google.com
Mon Sep 22 04:58:53 PDT 2014
Author: glider
Date: Mon Sep 22 06:58:52 2014
New Revision: 218243
URL: http://llvm.org/viewvc/llvm-project?rev=218243&view=rev
Log:
[ASan] Introduce the dump_instruction_bytes flag to print the faulting instruction upon SIGSEGV
When dump_instruction_bytes=1 and the instruction pointer doesn't point to the zero page, ASan prints 16 bytes starting at the instruction point.
Added:
compiler-rt/trunk/test/asan/TestCases/dump_instruction_bytes.cc
Modified:
compiler-rt/trunk/lib/asan/asan_flags.h
compiler-rt/trunk/lib/asan/asan_report.cc
compiler-rt/trunk/lib/asan/asan_rtl.cc
Modified: compiler-rt/trunk/lib/asan/asan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=218243&r1=218242&r2=218243&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Mon Sep 22 06:58:52 2014
@@ -65,6 +65,7 @@ struct Flags {
int detect_invalid_pointer_pairs;
bool detect_container_overflow;
int detect_odr_violation;
+ bool dump_instruction_bytes;
};
extern Flags asan_flags_dont_use_directly;
Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=218243&r1=218242&r2=218243&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Mon Sep 22 06:58:52 2014
@@ -86,15 +86,24 @@ class Decorator: public __sanitizer::San
}
}
const char *EndShadowByte() { return Default(); }
+ const char *MemoryByte() { return Magenta(); }
+ const char *EndMemoryByte() { return Default(); }
};
// ---------------------- Helper functions ----------------------- {{{1
-static void PrintShadowByte(InternalScopedString *str, const char *before,
- u8 byte, const char *after = "\n") {
+static void PrintMemoryByte(InternalScopedString *str, const char *before,
+ u8 byte, bool in_shadow, const char *after = "\n") {
Decorator d;
- str->append("%s%s%x%x%s%s", before, d.ShadowByte(byte), byte >> 4, byte & 15,
- d.EndShadowByte(), after);
+ str->append("%s%s%x%x%s%s", before,
+ in_shadow ? d.ShadowByte(byte) : d.MemoryByte(),
+ byte >> 4, byte & 15,
+ in_shadow ? d.EndShadowByte() : d.EndMemoryByte(), after);
+}
+
+static void PrintShadowByte(InternalScopedString *str, const char *before,
+ u8 byte, const char *after = "\n") {
+ PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);
}
static void PrintShadowBytes(InternalScopedString *str, const char *before,
@@ -149,6 +158,22 @@ static void PrintLegend(InternalScopedSt
PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic);
}
+void MaybeDumpInstructionBytes(uptr pc) {
+ if (!flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
+ return;
+ InternalScopedString str(1024);
+ str.append("First 16 instruction bytes at pc: ");
+ if (IsAccessibleMemoryRange(pc, 16)) {
+ for (int i = 0; i < 16; ++i) {
+ PrintMemoryByte(&str, "", ((u8 *)pc)[i], /*in_shadow*/false, " ");
+ }
+ str.append("\n");
+ } else {
+ str.append("unaccessible\n");
+ }
+ Report("%s", str.data());
+}
+
static void PrintShadowMemoryForAddress(uptr addr) {
if (!AddrIsInMem(addr)) return;
uptr shadow_addr = MemToShadow(addr);
@@ -636,6 +661,7 @@ void ReportSIGSEGV(const char *descripti
Printf("%s", d.EndWarning());
GET_STACK_TRACE_SIGNAL(pc, bp, context);
stack.Print();
+ MaybeDumpInstructionBytes(pc);
Printf("AddressSanitizer can not provide additional info.\n");
ReportErrorSummary("SEGV", &stack);
}
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=218243&r1=218242&r2=218243&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Mon Sep 22 06:58:52 2014
@@ -230,6 +230,9 @@ static void ParseFlagsFromString(Flags *
"If >=2, detect violation of One-Definition-Rule (ODR); "
"If ==1, detect ODR-violation only if the two variables "
"have different sizes");
+
+ ParseFlag(str, &f->dump_instruction_bytes, "dump_instruction_bytes",
+ "If true, dump 16 bytes starting at the instruction that caused SEGV");
}
void InitializeFlags(Flags *f, const char *env) {
@@ -283,6 +286,7 @@ void InitializeFlags(Flags *f, const cha
f->detect_invalid_pointer_pairs = 0;
f->detect_container_overflow = true;
f->detect_odr_violation = 2;
+ f->dump_instruction_bytes = false;
// Override from compile definition.
ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefinition());
Added: compiler-rt/trunk/test/asan/TestCases/dump_instruction_bytes.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/dump_instruction_bytes.cc?rev=218243&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/dump_instruction_bytes.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/dump_instruction_bytes.cc Mon Sep 22 06:58:52 2014
@@ -0,0 +1,20 @@
+// Check that ASan prints the faulting instruction bytes on
+// dump_instruction_bytes=1
+// RUN: %clangxx_asan %s -o %t
+// RUN: env ASAN_OPTIONS=dump_instruction_bytes=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
+
+int main() {
+#if defined(__x86_64__)
+ asm("movq $0, %rax");
+ asm("movl $0xcafebabe, 0x0(%rax)");
+#elif defined(i386)
+ asm("movl $0, %eax");
+ asm("movl $0xcafebabe, 0x0(%eax)");
+#endif
+ // CHECK-DUMP: First 16 instruction bytes at pc: c7 00 be ba fe ca
+ // CHECK-NODUMP-NOT: First 16 instruction bytes
+ return 0;
+}
+
+// XFAIL: arm
More information about the llvm-commits
mailing list