Improvements to tombstone output.
- Use "likelihood" instead of "probability" since that has connotations of being less precise, and our probability ordering isn't very precise anyway. - Hide the fault address with SEGV_MTEAERR because it is not available. - Pad the fault address with leading zeroes to make it clearer which bits of the top byte (and any following bytes such as PAC signature bits) are set. Bug: 206015287 Change-Id: I5e1e99b7f3e967c44781d8550bbd7158eb421b64
This commit is contained in:
parent
d0a4e710e9
commit
773acaa18e
4 changed files with 59 additions and 18 deletions
|
|
@ -340,7 +340,12 @@ TEST_F(CrasherTest, smoke) {
|
|||
|
||||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0xdead)");
|
||||
#ifdef __LP64__
|
||||
ASSERT_MATCH(result,
|
||||
R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x000000000000dead)");
|
||||
#else
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0000dead)");
|
||||
#endif
|
||||
|
||||
if (mte_supported()) {
|
||||
// Test that the default TAGGED_ADDR_CTRL value is set.
|
||||
|
|
@ -370,8 +375,7 @@ TEST_F(CrasherTest, tagged_fault_addr) {
|
|||
|
||||
// The address can either be tagged (new kernels) or untagged (old kernels).
|
||||
ASSERT_MATCH(
|
||||
result,
|
||||
R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr (0x100000000000dead|0xdead))");
|
||||
result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x[01]00000000000dead)");
|
||||
}
|
||||
|
||||
// Marked as weak to prevent the compiler from removing the malloc in the caller. In theory, the
|
||||
|
|
@ -422,6 +426,12 @@ static void SetTagCheckingLevelSync() {
|
|||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void SetTagCheckingLevelAsync() {
|
||||
if (mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, M_HEAP_TAGGING_LEVEL_ASYNC) == 0) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Number of iterations required to reliably guarantee a GWP-ASan crash.
|
||||
|
|
@ -653,6 +663,36 @@ TEST_P(SizeParamCrasherTest, mte_underflow) {
|
|||
#endif
|
||||
}
|
||||
|
||||
TEST_F(CrasherTest, mte_async) {
|
||||
#if defined(__aarch64__)
|
||||
if (!mte_supported()) {
|
||||
GTEST_SKIP() << "Requires MTE";
|
||||
}
|
||||
|
||||
int intercept_result;
|
||||
unique_fd output_fd;
|
||||
StartProcess([&]() {
|
||||
SetTagCheckingLevelAsync();
|
||||
volatile int* p = (volatile int*)malloc(16);
|
||||
p[-1] = 42;
|
||||
});
|
||||
|
||||
StartIntercept(&output_fd);
|
||||
FinishCrasher();
|
||||
AssertDeath(SIGSEGV);
|
||||
FinishIntercept(&intercept_result);
|
||||
|
||||
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
|
||||
|
||||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 8 \(SEGV_MTEAERR\), fault addr --------)");
|
||||
#else
|
||||
GTEST_SKIP() << "Requires aarch64";
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(CrasherTest, mte_multiple_causes) {
|
||||
#if defined(__aarch64__)
|
||||
if (!mte_supported()) {
|
||||
|
|
@ -703,7 +743,7 @@ TEST_F(CrasherTest, mte_multiple_causes) {
|
|||
for (const auto& result : log_sources) {
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
|
||||
ASSERT_THAT(result, HasSubstr("Note: multiple potential causes for this crash were detected, "
|
||||
"listing them in decreasing order of probability."));
|
||||
"listing them in decreasing order of likelihood."));
|
||||
// Adjacent untracked allocations may cause us to see the wrong underflow here (or only
|
||||
// overflows), so we can't match explicitly for an underflow message.
|
||||
ASSERT_MATCH(result,
|
||||
|
|
@ -890,7 +930,7 @@ TEST_F(CrasherTest, LD_PRELOAD) {
|
|||
|
||||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0xdead)");
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0+dead)");
|
||||
}
|
||||
|
||||
TEST_F(CrasherTest, abort) {
|
||||
|
|
@ -1940,7 +1980,7 @@ TEST_F(CrasherTest, fault_address_before_first_map) {
|
|||
|
||||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x1024)");
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0+1024)");
|
||||
|
||||
ASSERT_MATCH(result, R"(\nmemory map \(.*\):\n)");
|
||||
|
||||
|
|
@ -1970,8 +2010,8 @@ TEST_F(CrasherTest, fault_address_after_last_map) {
|
|||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
|
||||
std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr )";
|
||||
match_str += android::base::StringPrintf("0x%" PRIxPTR, crash_uptr);
|
||||
std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x)";
|
||||
match_str += format_full_pointer(crash_uptr);
|
||||
ASSERT_MATCH(result, match_str);
|
||||
|
||||
ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->)\n)");
|
||||
|
|
@ -2018,8 +2058,8 @@ TEST_F(CrasherTest, fault_address_between_maps) {
|
|||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
|
||||
std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr )";
|
||||
match_str += android::base::StringPrintf("%p", middle_ptr);
|
||||
std::string match_str = R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x)";
|
||||
match_str += format_full_pointer(reinterpret_cast<uintptr_t>(middle_ptr));
|
||||
ASSERT_MATCH(result, match_str);
|
||||
|
||||
ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->)\n)");
|
||||
|
|
@ -2056,8 +2096,8 @@ TEST_F(CrasherTest, fault_address_in_map) {
|
|||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
|
||||
std::string match_str = R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\), fault addr )";
|
||||
match_str += android::base::StringPrintf("%p", ptr);
|
||||
std::string match_str = R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\), fault addr 0x)";
|
||||
match_str += format_full_pointer(reinterpret_cast<uintptr_t>(ptr));
|
||||
ASSERT_MATCH(result, match_str);
|
||||
|
||||
ASSERT_MATCH(result, R"(\nmemory map \(.*\): \(fault address prefixed with --->)\n)");
|
||||
|
|
@ -2181,7 +2221,7 @@ TEST_F(CrasherTest, verify_dex_pc_with_function_name) {
|
|||
ConsumeFd(std::move(output_fd), &result);
|
||||
|
||||
// Verify the process crashed properly.
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0)");
|
||||
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr 0x0*)");
|
||||
|
||||
// Now verify that the dex_pc frame includes a proper function name.
|
||||
ASSERT_MATCH(result, R"( \[anon:dex\] \(Main\.\<init\>\+2)");
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ void ScudoCrashData::DumpCause(log_t* log, unwindstack::Unwinder* unwinder) cons
|
|||
if (error_info_.reports[1].error_type != UNKNOWN) {
|
||||
_LOG(log, logtype::HEADER,
|
||||
"\nNote: multiple potential causes for this crash were detected, listing them in "
|
||||
"decreasing order of probability.\n");
|
||||
"decreasing order of likelihood.\n");
|
||||
}
|
||||
|
||||
size_t report_num = 0;
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ static void print_tag_dump(CallbackType callback, const Tombstone& tombstone) {
|
|||
|
||||
static void print_main_thread(CallbackType callback, const Tombstone& tombstone,
|
||||
const Thread& thread) {
|
||||
int word_size = pointer_width(tombstone);
|
||||
print_thread_header(callback, tombstone, thread, true);
|
||||
|
||||
const Signal& signal_info = tombstone.signal_info();
|
||||
|
|
@ -307,7 +308,7 @@ static void print_main_thread(CallbackType callback, const Tombstone& tombstone,
|
|||
} else {
|
||||
std::string fault_addr_desc;
|
||||
if (signal_info.has_fault_address()) {
|
||||
fault_addr_desc = StringPrintf("0x%" PRIx64, signal_info.fault_address());
|
||||
fault_addr_desc = StringPrintf("0x%0*" PRIx64, 2 * word_size, signal_info.fault_address());
|
||||
} else {
|
||||
fault_addr_desc = "--------";
|
||||
}
|
||||
|
|
@ -331,7 +332,7 @@ static void print_main_thread(CallbackType callback, const Tombstone& tombstone,
|
|||
if (tombstone.causes_size() > 1) {
|
||||
CBS("");
|
||||
CBL("Note: multiple potential causes for this crash were detected, listing them in decreasing "
|
||||
"order of probability.");
|
||||
"order of likelihood.");
|
||||
}
|
||||
|
||||
for (const Cause& cause : tombstone.causes()) {
|
||||
|
|
@ -369,7 +370,6 @@ static void print_main_thread(CallbackType callback, const Tombstone& tombstone,
|
|||
return;
|
||||
}
|
||||
|
||||
int word_size = pointer_width(tombstone);
|
||||
const auto format_pointer = [word_size](uint64_t ptr) -> std::string {
|
||||
if (word_size == 8) {
|
||||
uint64_t top = ptr >> 32;
|
||||
|
|
|
|||
|
|
@ -275,9 +275,10 @@ bool signal_has_si_addr(const siginfo_t* si) {
|
|||
case SIGBUS:
|
||||
case SIGFPE:
|
||||
case SIGILL:
|
||||
case SIGSEGV:
|
||||
case SIGTRAP:
|
||||
return true;
|
||||
case SIGSEGV:
|
||||
return si->si_code != SEGV_MTEAERR;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue