From dd5a80dff57f565aedfa46481defe8c7bc5a2f4e Mon Sep 17 00:00:00 2001 From: Mitch Phillips Date: Mon, 13 Mar 2023 15:08:17 -0700 Subject: [PATCH] [debuggerd] New protocol to AM to handle recoverable crashes. See aosp/2485756 for more details, but this patch introduces a new protocol between debuggerd and ActivityManager. This new protocol allows ActivityManager to correctly handle recoverable crashes. Bug: 270720163 Test: atest CtsGwpAsanTestCases Change-Id: Icac6262d608dd57a5daf51699064ab28b0c4703f --- debuggerd/crash_dump.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp index 442392d30..4ddd38a86 100644 --- a/debuggerd/crash_dump.cpp +++ b/debuggerd/crash_dump.cpp @@ -142,7 +142,8 @@ static bool ptrace_interrupt(pid_t tid, int* received_signal) { return false; } -static bool activity_manager_notify(pid_t pid, int signal, const std::string& amfd_data) { +static bool activity_manager_notify(pid_t pid, int signal, const std::string& amfd_data, + bool recoverable_gwp_asan_crash) { ATRACE_CALL(); android::base::unique_fd amfd(socket_local_client( "/data/system/ndebugsocket", ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM)); @@ -165,19 +166,32 @@ static bool activity_manager_notify(pid_t pid, int signal, const std::string& am return false; } - // Activity Manager protocol: binary 32-bit network-byte-order ints for the - // pid and signal number, followed by the raw text of the dump, culminating - // in a zero byte that marks end-of-data. + // Activity Manager protocol: + // - 32-bit network-byte-order: pid + // - 32-bit network-byte-order: signal number + // - byte: recoverable_gwp_asan_crash + // - bytes: raw text of the dump + // - null terminator + uint32_t datum = htonl(pid); - if (!android::base::WriteFully(amfd, &datum, 4)) { + if (!android::base::WriteFully(amfd, &datum, sizeof(datum))) { PLOG(ERROR) << "AM pid write failed"; return false; } + datum = htonl(signal); - if (!android::base::WriteFully(amfd, &datum, 4)) { - PLOG(ERROR) << "AM signal write failed"; + if (!android::base::WriteFully(amfd, &datum, sizeof(datum))) { + PLOG(ERROR) << "AM signo write failed"; return false; } + + uint8_t recoverable_gwp_asan_crash_byte = recoverable_gwp_asan_crash ? 1 : 0; + if (!android::base::WriteFully(amfd, &recoverable_gwp_asan_crash_byte, + sizeof(recoverable_gwp_asan_crash_byte))) { + PLOG(ERROR) << "AM recoverable_gwp_asan_crash_byte write failed"; + return false; + } + if (!android::base::WriteFully(amfd, amfd_data.c_str(), amfd_data.size() + 1)) { PLOG(ERROR) << "AM data write failed"; return false; @@ -651,10 +665,10 @@ int main(int argc, char** argv) { } } - if (fatal_signal && !recoverable_gwp_asan_crash) { + if (fatal_signal) { // Don't try to notify ActivityManager if it just crashed, or we might hang until timeout. if (thread_info[target_process].thread_name != "system_server") { - activity_manager_notify(target_process, signo, amfd_data); + activity_manager_notify(target_process, signo, amfd_data, recoverable_gwp_asan_crash); } }