diff options
author | Elliott Hughes | 2018-05-30 14:55:04 -0500 |
---|---|---|
committer | Elliott Hughes | 2018-05-30 14:58:43 -0500 |
commit | 2baf443a21f3d7c763ffcd36b0eb0445bf05d8e0 (patch) | |
tree | 2d6233956ad2c7f9dd83f887c9077744e8b2ab76 /debuggerd | |
parent | d580c441ab45a6b7278da003e19af64e9ea2cc71 (diff) | |
download | platform-system-core-2baf443a21f3d7c763ffcd36b0eb0445bf05d8e0.tar.gz platform-system-core-2baf443a21f3d7c763ffcd36b0eb0445bf05d8e0.tar.xz platform-system-core-2baf443a21f3d7c763ffcd36b0eb0445bf05d8e0.zip |
Improve SIGILL support.
Include the illegal instruction in the header if we get a
SIGILL. Otherwise (since these tend to be one-off bit flips), we don't
usually have any information to try to confirm our suspicion that any
given instance is actually a one-off bit flip.
Also add `SIGILL` as a crasher option to easily generate such crashes.
Before:
signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0xab1456da
After:
signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0xab1456da (*pc=0xe7f0def0)
Bug: http://b/77274448
Test: ran crasher
Change-Id: I5f8dedca5eea2b117b1b1e48430214b38e1366ed
Diffstat (limited to 'debuggerd')
-rw-r--r-- | debuggerd/crasher/crasher.cpp | 11 | ||||
-rw-r--r-- | debuggerd/libdebuggerd/tombstone.cpp | 15 |
2 files changed, 22 insertions, 4 deletions
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp index 4b32b9d36..f31337d70 100644 --- a/debuggerd/crasher/crasher.cpp +++ b/debuggerd/crasher/crasher.cpp | |||
@@ -197,6 +197,7 @@ static int usage() { | |||
197 | fprintf(stderr, " LOG-FATAL call libbase LOG(FATAL)\n"); | 197 | fprintf(stderr, " LOG-FATAL call libbase LOG(FATAL)\n"); |
198 | fprintf(stderr, "\n"); | 198 | fprintf(stderr, "\n"); |
199 | fprintf(stderr, " SIGFPE cause a SIGFPE\n"); | 199 | fprintf(stderr, " SIGFPE cause a SIGFPE\n"); |
200 | fprintf(stderr, " SIGILL cause a SIGILL\n"); | ||
200 | fprintf(stderr, " SIGSEGV cause a SIGSEGV at address 0x0 (synonym: crash)\n"); | 201 | fprintf(stderr, " SIGSEGV cause a SIGSEGV at address 0x0 (synonym: crash)\n"); |
201 | fprintf(stderr, " SIGSEGV-non-null cause a SIGSEGV at a non-zero address\n"); | 202 | fprintf(stderr, " SIGSEGV-non-null cause a SIGSEGV at a non-zero address\n"); |
202 | fprintf(stderr, " SIGSEGV-unmapped mmap/munmap a region of memory and then attempt to access it\n"); | 203 | fprintf(stderr, " SIGSEGV-unmapped mmap/munmap a region of memory and then attempt to access it\n"); |
@@ -268,6 +269,16 @@ noinline int do_action(const char* arg) { | |||
268 | } else if (!strcasecmp(arg, "SIGFPE")) { | 269 | } else if (!strcasecmp(arg, "SIGFPE")) { |
269 | raise(SIGFPE); | 270 | raise(SIGFPE); |
270 | return EXIT_SUCCESS; | 271 | return EXIT_SUCCESS; |
272 | } else if (!strcasecmp(arg, "SIGILL")) { | ||
273 | #if defined(__aarch64__) | ||
274 | __asm__ volatile(".word 0\n"); | ||
275 | #elif defined(__arm__) | ||
276 | __asm__ volatile(".word 0xe7f0def0\n"); | ||
277 | #elif defined(__i386__) || defined(__x86_64__) | ||
278 | __asm__ volatile("ud2\n"); | ||
279 | #else | ||
280 | #error | ||
281 | #endif | ||
271 | } else if (!strcasecmp(arg, "SIGTRAP")) { | 282 | } else if (!strcasecmp(arg, "SIGTRAP")) { |
272 | raise(SIGTRAP); | 283 | raise(SIGTRAP); |
273 | return EXIT_SUCCESS; | 284 | return EXIT_SUCCESS; |
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index e11be1ea7..433bb4657 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp | |||
@@ -102,10 +102,17 @@ static void dump_probable_cause(log_t* log, const siginfo_t* si) { | |||
102 | if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str()); | 102 | if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str()); |
103 | } | 103 | } |
104 | 104 | ||
105 | static void dump_signal_info(log_t* log, const ThreadInfo& thread_info) { | 105 | static void dump_signal_info(log_t* log, const ThreadInfo& thread_info, Memory* process_memory) { |
106 | char addr_desc[32]; // ", fault addr 0x1234" | 106 | char addr_desc[64]; // ", fault addr 0x1234" |
107 | if (signal_has_si_addr(thread_info.siginfo)) { | 107 | if (signal_has_si_addr(thread_info.siginfo)) { |
108 | snprintf(addr_desc, sizeof(addr_desc), "%p", thread_info.siginfo->si_addr); | 108 | void* addr = thread_info.siginfo->si_addr; |
109 | if (thread_info.siginfo->si_signo == SIGILL) { | ||
110 | uint32_t instruction = {}; | ||
111 | process_memory->Read(reinterpret_cast<uint64_t>(addr), &instruction, sizeof(instruction)); | ||
112 | snprintf(addr_desc, sizeof(addr_desc), "%p (*pc=%#08x)", addr, instruction); | ||
113 | } else { | ||
114 | snprintf(addr_desc, sizeof(addr_desc), "%p", addr); | ||
115 | } | ||
109 | } else { | 116 | } else { |
110 | snprintf(addr_desc, sizeof(addr_desc), "--------"); | 117 | snprintf(addr_desc, sizeof(addr_desc), "--------"); |
111 | } | 118 | } |
@@ -418,7 +425,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, | |||
418 | dump_thread_info(log, thread_info); | 425 | dump_thread_info(log, thread_info); |
419 | 426 | ||
420 | if (thread_info.siginfo) { | 427 | if (thread_info.siginfo) { |
421 | dump_signal_info(log, thread_info); | 428 | dump_signal_info(log, thread_info, process_memory); |
422 | } | 429 | } |
423 | 430 | ||
424 | if (primary_thread) { | 431 | if (primary_thread) { |