debuggerd_handler: don't assume that abort message implies fatal.
Applications can set abort messages via android_set_abort_message without actually aborting. This leads to following non-fatal dumps printing their output to logcat in the same format as a regular crash. Bug: http://b/37754992 Test: debuggerd_test Change-Id: I9c5e942984dfda36448860202b0ff1c2950bdd07
This commit is contained in:
parent
a0bf415cad
commit
e06f2a4886
2 changed files with 38 additions and 7 deletions
|
@ -78,6 +78,14 @@ constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb";
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASSERT_NOT_MATCH(str, pattern) \
|
||||
do { \
|
||||
std::regex r((pattern)); \
|
||||
if (std::regex_search((str), r)) { \
|
||||
FAIL() << "regex mismatch: expected to not find " << (pattern) << " in: \n" << (str); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd) {
|
||||
intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName,
|
||||
ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
|
||||
|
@ -226,12 +234,14 @@ void CrasherTest::AssertDeath(int signo) {
|
|||
FAIL() << "failed to wait for crasher: " << strerror(errno);
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
FAIL() << "crasher failed to exec: " << strerror(WEXITSTATUS(status));
|
||||
} else if (!WIFSIGNALED(status)) {
|
||||
FAIL() << "crasher didn't terminate via a signal";
|
||||
if (signo == 0) {
|
||||
ASSERT_TRUE(WIFEXITED(status));
|
||||
ASSERT_EQ(0, WEXITSTATUS(signo));
|
||||
} else {
|
||||
ASSERT_FALSE(WIFEXITED(status));
|
||||
ASSERT_TRUE(WIFSIGNALED(status)) << "crasher didn't terminate via a signal";
|
||||
ASSERT_EQ(signo, WTERMSIG(status));
|
||||
}
|
||||
ASSERT_EQ(signo, WTERMSIG(status));
|
||||
crasher_pid = -1;
|
||||
}
|
||||
|
||||
|
@ -336,6 +346,26 @@ TEST_F(CrasherTest, abort_message) {
|
|||
ASSERT_MATCH(result, R"(Abort message: 'abort message goes here')");
|
||||
}
|
||||
|
||||
TEST_F(CrasherTest, abort_message_backtrace) {
|
||||
int intercept_result;
|
||||
unique_fd output_fd;
|
||||
StartProcess([]() {
|
||||
android_set_abort_message("not actually aborting");
|
||||
raise(DEBUGGER_SIGNAL);
|
||||
exit(0);
|
||||
});
|
||||
StartIntercept(&output_fd);
|
||||
FinishCrasher();
|
||||
AssertDeath(0);
|
||||
FinishIntercept(&intercept_result);
|
||||
|
||||
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
|
||||
|
||||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
ASSERT_NOT_MATCH(result, R"(Abort message:)");
|
||||
}
|
||||
|
||||
TEST_F(CrasherTest, intercept_timeout) {
|
||||
int intercept_result;
|
||||
unique_fd output_fd;
|
||||
|
|
|
@ -389,8 +389,9 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
|
|||
|
||||
log_signal_summary(signal_number, info);
|
||||
|
||||
// Populate si_value with the abort message address, if found.
|
||||
if (abort_message) {
|
||||
// If this was a fatal crash, populate si_value with the abort message address if possible.
|
||||
// Note that applications can set an abort message without aborting.
|
||||
if (abort_message && signal_number != DEBUGGER_SIGNAL) {
|
||||
info->si_value.sival_ptr = abort_message;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue