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
This commit is contained in:
Elliott Hughes 2018-05-30 12:55:04 -07:00
parent d580c441ab
commit 2baf443a21
2 changed files with 22 additions and 4 deletions

View File

@ -197,6 +197,7 @@ static int usage() {
fprintf(stderr, " LOG-FATAL call libbase LOG(FATAL)\n");
fprintf(stderr, "\n");
fprintf(stderr, " SIGFPE cause a SIGFPE\n");
fprintf(stderr, " SIGILL cause a SIGILL\n");
fprintf(stderr, " SIGSEGV cause a SIGSEGV at address 0x0 (synonym: crash)\n");
fprintf(stderr, " SIGSEGV-non-null cause a SIGSEGV at a non-zero address\n");
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) {
} else if (!strcasecmp(arg, "SIGFPE")) {
raise(SIGFPE);
return EXIT_SUCCESS;
} else if (!strcasecmp(arg, "SIGILL")) {
#if defined(__aarch64__)
__asm__ volatile(".word 0\n");
#elif defined(__arm__)
__asm__ volatile(".word 0xe7f0def0\n");
#elif defined(__i386__) || defined(__x86_64__)
__asm__ volatile("ud2\n");
#else
#error
#endif
} else if (!strcasecmp(arg, "SIGTRAP")) {
raise(SIGTRAP);
return EXIT_SUCCESS;

View File

@ -102,10 +102,17 @@ static void dump_probable_cause(log_t* log, const siginfo_t* si) {
if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str());
}
static void dump_signal_info(log_t* log, const ThreadInfo& thread_info) {
char addr_desc[32]; // ", fault addr 0x1234"
static void dump_signal_info(log_t* log, const ThreadInfo& thread_info, Memory* process_memory) {
char addr_desc[64]; // ", fault addr 0x1234"
if (signal_has_si_addr(thread_info.siginfo)) {
snprintf(addr_desc, sizeof(addr_desc), "%p", thread_info.siginfo->si_addr);
void* addr = thread_info.siginfo->si_addr;
if (thread_info.siginfo->si_signo == SIGILL) {
uint32_t instruction = {};
process_memory->Read(reinterpret_cast<uint64_t>(addr), &instruction, sizeof(instruction));
snprintf(addr_desc, sizeof(addr_desc), "%p (*pc=%#08x)", addr, instruction);
} else {
snprintf(addr_desc, sizeof(addr_desc), "%p", addr);
}
} else {
snprintf(addr_desc, sizeof(addr_desc), "--------");
}
@ -418,7 +425,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory,
dump_thread_info(log, thread_info);
if (thread_info.siginfo) {
dump_signal_info(log, thread_info);
dump_signal_info(log, thread_info, process_memory);
}
if (primary_thread) {