[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