Loading debuggerd/backtrace.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sys/ptrace.h> #include <memory> #include <string> #include <backtrace/Backtrace.h> Loading Loading @@ -96,11 +97,11 @@ static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) { } } void dump_backtrace(int fd, int amfd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings) { void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings, std::string* amfd_data) { log_t log; log.tfd = fd; log.amfd = amfd; log.amfd_data = amfd_data; dump_process_header(&log, pid); dump_thread(&log, map, pid, tid); Loading debuggerd/backtrace.h +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <sys/types.h> #include <set> #include <string> #include "utility.h" Loading @@ -28,8 +29,8 @@ class BacktraceMap; // Dumps a backtrace using a format similar to what Dalvik uses so that the result // can be intermixed in a bug report. void dump_backtrace(int fd, int amfd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings); void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings, std::string* amfd_data); /* Dumps the backtrace in the backtrace data structure to the log. */ void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix); Loading debuggerd/debuggerd.cpp +58 −7 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ * limitations under the License. */ #include <arpa/inet.h> #include <dirent.h> #include <elf.h> #include <errno.h> Loading @@ -32,12 +33,15 @@ #include <sys/un.h> #include <time.h> #include <memory> #include <set> #include <string> #include <selinux/android.h> #include <log/logger.h> #include <android-base/file.h> #include <android-base/unique_fd.h> #include <cutils/debugger.h> #include <cutils/properties.h> Loading Loading @@ -287,6 +291,41 @@ static int activity_manager_connect() { return amfd.release(); } static void activity_manager_write(int pid, int signal, int amfd, const std::string& amfd_data) { if (amfd == -1) { return; } // 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. uint32_t datum = htonl(pid); if (!android::base::WriteFully(amfd, &datum, 4)) { ALOGE("AM pid write failed: %s\n", strerror(errno)); return; } datum = htonl(signal); if (!android::base::WriteFully(amfd, &datum, 4)) { ALOGE("AM signal write failed: %s\n", strerror(errno)); return; } if (!android::base::WriteFully(amfd, amfd_data.c_str(), amfd_data.size())) { ALOGE("AM data write failed: %s\n", strerror(errno)); return; } // Send EOD to the Activity Manager, then wait for its ack to avoid racing // ahead and killing the target out from under it. uint8_t eodMarker = 0; if (!android::base::WriteFully(amfd, &eodMarker, 1)) { ALOGE("AM eod write failed: %s\n", strerror(errno)); return; } // 3 sec timeout reading the ack; we're fine if the read fails. android::base::ReadFully(amfd, &eodMarker, 1); } static bool should_attach_gdb(const debugger_request_t& request) { if (request.action == DEBUGGER_ACTION_CRASH) { return property_get_bool("debug.debuggerd.wait_for_gdb", false); Loading Loading @@ -414,7 +453,7 @@ static void ptrace_siblings(pid_t pid, pid_t main_tid, std::set<pid_t>& tids) { static bool perform_dump(const debugger_request_t& request, int fd, int tombstone_fd, BacktraceMap* backtrace_map, const std::set<pid_t>& siblings, int* crash_signal, int amfd) { int* crash_signal, std::string* amfd_data) { if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) { ALOGE("debuggerd: failed to respond to client: %s\n", strerror(errno)); return false; Loading @@ -432,10 +471,10 @@ static bool perform_dump(const debugger_request_t& request, int fd, int tombston if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) { ALOGV("debuggerd: stopped -- dumping to tombstone"); engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal, request.original_si_code, request.abort_msg_address, amfd); request.original_si_code, request.abort_msg_address, amfd_data); } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) { ALOGV("debuggerd: stopped -- dumping to fd"); dump_backtrace(fd, -1, backtrace_map, request.pid, request.tid, siblings); dump_backtrace(fd, backtrace_map, request.pid, request.tid, siblings, nullptr); } else { ALOGV("debuggerd: stopped -- continuing"); if (ptrace(PTRACE_CONT, request.tid, 0, 0) != 0) { Loading @@ -458,7 +497,7 @@ static bool perform_dump(const debugger_request_t& request, int fd, int tombston ALOGV("stopped -- fatal signal\n"); *crash_signal = signal; engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal, request.original_si_code, request.abort_msg_address, amfd); request.original_si_code, request.abort_msg_address, amfd_data); break; default: Loading Loading @@ -545,9 +584,11 @@ static void worker_process(int fd, debugger_request_t& request) { std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(request.pid)); int amfd = -1; std::unique_ptr<std::string> amfd_data; if (request.action == DEBUGGER_ACTION_CRASH) { // Connect to the activity manager before dropping privileges. amfd = activity_manager_connect(); amfd_data.reset(new std::string); } bool succeeded = false; Loading @@ -560,11 +601,11 @@ static void worker_process(int fd, debugger_request_t& request) { int crash_signal = SIGKILL; succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings, &crash_signal, amfd); &crash_signal, amfd_data.get()); if (succeeded) { if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) { if (!tombstone_path.empty()) { write(fd, tombstone_path.c_str(), tombstone_path.length()); android::base::WriteFully(fd, tombstone_path.c_str(), tombstone_path.length()); } } } Loading @@ -577,6 +618,13 @@ static void worker_process(int fd, debugger_request_t& request) { } } if (!attach_gdb) { // Tell the Activity Manager about the crashing process. If we are // waiting for gdb to attach, do not send this or Activity Manager // might kill the process before anyone can attach. activity_manager_write(request.pid, crash_signal, amfd, *amfd_data.get()); } if (ptrace(PTRACE_DETACH, request.tid, 0, 0) != 0) { ALOGE("debuggerd: ptrace detach from %d failed: %s", request.tid, strerror(errno)); } Loading @@ -593,9 +641,12 @@ static void worker_process(int fd, debugger_request_t& request) { } // Wait for gdb, if requested. if (attach_gdb && succeeded) { if (attach_gdb) { wait_for_user_action(request); // Now tell the activity manager about this process. activity_manager_write(request.pid, crash_signal, amfd, *amfd_data.get()); // Tell the signal process to send SIGCONT to the target. if (!send_signal(request.pid, 0, SIGCONT)) { ALOGE("debuggerd: failed to resume process %d: %s", request.pid, strerror(errno)); Loading debuggerd/test/dump_memory_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ class DumpMemoryTest : public ::testing::Test { } log_.tfd = tombstone_fd; log_.amfd = -1; log_.amfd_data = nullptr; log_.crashed_tid = 12; log_.current_tid = 12; log_.should_retrieve_logcat = false; Loading debuggerd/test/tombstone_test.cpp +35 −1 Original line number Diff line number Diff line Loading @@ -68,7 +68,8 @@ class TombstoneTest : public ::testing::Test { } log_.tfd = tombstone_fd; log_.amfd = -1; amfd_data_.clear(); log_.amfd_data = &amfd_data_; log_.crashed_tid = 12; log_.current_tid = 12; log_.should_retrieve_logcat = false; Loading @@ -90,6 +91,7 @@ class TombstoneTest : public ::testing::Test { std::unique_ptr<BacktraceMock> backtrace_mock_; log_t log_; std::string amfd_data_; }; TEST_F(TombstoneTest, single_map) { Loading Loading @@ -117,6 +119,8 @@ TEST_F(TombstoneTest, single_map) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -150,6 +154,8 @@ TEST_F(TombstoneTest, single_map_elf_build_id) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -189,6 +195,8 @@ TEST_F(TombstoneTest, single_map_no_build_id) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -251,6 +259,8 @@ TEST_F(TombstoneTest, multiple_maps) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -305,6 +315,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_before) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -359,6 +371,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_between) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -411,6 +425,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -469,6 +485,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_after) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -501,6 +519,8 @@ TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG Cannot get siginfo for 100: Bad address\n\n", getFakeLogPrint().c_str()); Loading Loading @@ -562,6 +582,8 @@ TEST_F(TombstoneTest, multiple_maps_check_signal_has_si_addr) { << "Signal " << si.si_signo << " is not expected to include an address."; } ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading @@ -582,6 +604,8 @@ TEST_F(TombstoneTest, dump_signal_info_error) { ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG cannot get siginfo: Bad address\n\n", getFakeLogPrint().c_str()); ASSERT_STREQ("", amfd_data_.c_str()); } TEST_F(TombstoneTest, dump_log_file_error) { Loading @@ -596,4 +620,14 @@ TEST_F(TombstoneTest, dump_log_file_error) { ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n", getFakeLogPrint().c_str()); ASSERT_STREQ("", amfd_data_.c_str()); } TEST_F(TombstoneTest, dump_header_info) { dump_header_info(&log_); std::string expected = "Build fingerprint: 'unknown'\nRevision: 'unknown'\n"; expected += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING); ASSERT_STREQ(expected.c_str(), amfd_data_.c_str()); } Loading
debuggerd/backtrace.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sys/ptrace.h> #include <memory> #include <string> #include <backtrace/Backtrace.h> Loading Loading @@ -96,11 +97,11 @@ static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) { } } void dump_backtrace(int fd, int amfd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings) { void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings, std::string* amfd_data) { log_t log; log.tfd = fd; log.amfd = amfd; log.amfd_data = amfd_data; dump_process_header(&log, pid); dump_thread(&log, map, pid, tid); Loading
debuggerd/backtrace.h +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <sys/types.h> #include <set> #include <string> #include "utility.h" Loading @@ -28,8 +29,8 @@ class BacktraceMap; // Dumps a backtrace using a format similar to what Dalvik uses so that the result // can be intermixed in a bug report. void dump_backtrace(int fd, int amfd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings); void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::set<pid_t>& siblings, std::string* amfd_data); /* Dumps the backtrace in the backtrace data structure to the log. */ void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix); Loading
debuggerd/debuggerd.cpp +58 −7 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ * limitations under the License. */ #include <arpa/inet.h> #include <dirent.h> #include <elf.h> #include <errno.h> Loading @@ -32,12 +33,15 @@ #include <sys/un.h> #include <time.h> #include <memory> #include <set> #include <string> #include <selinux/android.h> #include <log/logger.h> #include <android-base/file.h> #include <android-base/unique_fd.h> #include <cutils/debugger.h> #include <cutils/properties.h> Loading Loading @@ -287,6 +291,41 @@ static int activity_manager_connect() { return amfd.release(); } static void activity_manager_write(int pid, int signal, int amfd, const std::string& amfd_data) { if (amfd == -1) { return; } // 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. uint32_t datum = htonl(pid); if (!android::base::WriteFully(amfd, &datum, 4)) { ALOGE("AM pid write failed: %s\n", strerror(errno)); return; } datum = htonl(signal); if (!android::base::WriteFully(amfd, &datum, 4)) { ALOGE("AM signal write failed: %s\n", strerror(errno)); return; } if (!android::base::WriteFully(amfd, amfd_data.c_str(), amfd_data.size())) { ALOGE("AM data write failed: %s\n", strerror(errno)); return; } // Send EOD to the Activity Manager, then wait for its ack to avoid racing // ahead and killing the target out from under it. uint8_t eodMarker = 0; if (!android::base::WriteFully(amfd, &eodMarker, 1)) { ALOGE("AM eod write failed: %s\n", strerror(errno)); return; } // 3 sec timeout reading the ack; we're fine if the read fails. android::base::ReadFully(amfd, &eodMarker, 1); } static bool should_attach_gdb(const debugger_request_t& request) { if (request.action == DEBUGGER_ACTION_CRASH) { return property_get_bool("debug.debuggerd.wait_for_gdb", false); Loading Loading @@ -414,7 +453,7 @@ static void ptrace_siblings(pid_t pid, pid_t main_tid, std::set<pid_t>& tids) { static bool perform_dump(const debugger_request_t& request, int fd, int tombstone_fd, BacktraceMap* backtrace_map, const std::set<pid_t>& siblings, int* crash_signal, int amfd) { int* crash_signal, std::string* amfd_data) { if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) { ALOGE("debuggerd: failed to respond to client: %s\n", strerror(errno)); return false; Loading @@ -432,10 +471,10 @@ static bool perform_dump(const debugger_request_t& request, int fd, int tombston if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) { ALOGV("debuggerd: stopped -- dumping to tombstone"); engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal, request.original_si_code, request.abort_msg_address, amfd); request.original_si_code, request.abort_msg_address, amfd_data); } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) { ALOGV("debuggerd: stopped -- dumping to fd"); dump_backtrace(fd, -1, backtrace_map, request.pid, request.tid, siblings); dump_backtrace(fd, backtrace_map, request.pid, request.tid, siblings, nullptr); } else { ALOGV("debuggerd: stopped -- continuing"); if (ptrace(PTRACE_CONT, request.tid, 0, 0) != 0) { Loading @@ -458,7 +497,7 @@ static bool perform_dump(const debugger_request_t& request, int fd, int tombston ALOGV("stopped -- fatal signal\n"); *crash_signal = signal; engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal, request.original_si_code, request.abort_msg_address, amfd); request.original_si_code, request.abort_msg_address, amfd_data); break; default: Loading Loading @@ -545,9 +584,11 @@ static void worker_process(int fd, debugger_request_t& request) { std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(request.pid)); int amfd = -1; std::unique_ptr<std::string> amfd_data; if (request.action == DEBUGGER_ACTION_CRASH) { // Connect to the activity manager before dropping privileges. amfd = activity_manager_connect(); amfd_data.reset(new std::string); } bool succeeded = false; Loading @@ -560,11 +601,11 @@ static void worker_process(int fd, debugger_request_t& request) { int crash_signal = SIGKILL; succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings, &crash_signal, amfd); &crash_signal, amfd_data.get()); if (succeeded) { if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) { if (!tombstone_path.empty()) { write(fd, tombstone_path.c_str(), tombstone_path.length()); android::base::WriteFully(fd, tombstone_path.c_str(), tombstone_path.length()); } } } Loading @@ -577,6 +618,13 @@ static void worker_process(int fd, debugger_request_t& request) { } } if (!attach_gdb) { // Tell the Activity Manager about the crashing process. If we are // waiting for gdb to attach, do not send this or Activity Manager // might kill the process before anyone can attach. activity_manager_write(request.pid, crash_signal, amfd, *amfd_data.get()); } if (ptrace(PTRACE_DETACH, request.tid, 0, 0) != 0) { ALOGE("debuggerd: ptrace detach from %d failed: %s", request.tid, strerror(errno)); } Loading @@ -593,9 +641,12 @@ static void worker_process(int fd, debugger_request_t& request) { } // Wait for gdb, if requested. if (attach_gdb && succeeded) { if (attach_gdb) { wait_for_user_action(request); // Now tell the activity manager about this process. activity_manager_write(request.pid, crash_signal, amfd, *amfd_data.get()); // Tell the signal process to send SIGCONT to the target. if (!send_signal(request.pid, 0, SIGCONT)) { ALOGE("debuggerd: failed to resume process %d: %s", request.pid, strerror(errno)); Loading
debuggerd/test/dump_memory_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ class DumpMemoryTest : public ::testing::Test { } log_.tfd = tombstone_fd; log_.amfd = -1; log_.amfd_data = nullptr; log_.crashed_tid = 12; log_.current_tid = 12; log_.should_retrieve_logcat = false; Loading
debuggerd/test/tombstone_test.cpp +35 −1 Original line number Diff line number Diff line Loading @@ -68,7 +68,8 @@ class TombstoneTest : public ::testing::Test { } log_.tfd = tombstone_fd; log_.amfd = -1; amfd_data_.clear(); log_.amfd_data = &amfd_data_; log_.crashed_tid = 12; log_.current_tid = 12; log_.should_retrieve_logcat = false; Loading @@ -90,6 +91,7 @@ class TombstoneTest : public ::testing::Test { std::unique_ptr<BacktraceMock> backtrace_mock_; log_t log_; std::string amfd_data_; }; TEST_F(TombstoneTest, single_map) { Loading Loading @@ -117,6 +119,8 @@ TEST_F(TombstoneTest, single_map) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -150,6 +154,8 @@ TEST_F(TombstoneTest, single_map_elf_build_id) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -189,6 +195,8 @@ TEST_F(TombstoneTest, single_map_no_build_id) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -251,6 +259,8 @@ TEST_F(TombstoneTest, multiple_maps) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -305,6 +315,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_before) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -359,6 +371,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_between) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -411,6 +425,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -469,6 +485,8 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_after) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading Loading @@ -501,6 +519,8 @@ TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) { #endif ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG Cannot get siginfo for 100: Bad address\n\n", getFakeLogPrint().c_str()); Loading Loading @@ -562,6 +582,8 @@ TEST_F(TombstoneTest, multiple_maps_check_signal_has_si_addr) { << "Signal " << si.si_signo << " is not expected to include an address."; } ASSERT_STREQ("", amfd_data_.c_str()); // Verify that the log buf is empty, and no error messages. ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("", getFakeLogPrint().c_str()); Loading @@ -582,6 +604,8 @@ TEST_F(TombstoneTest, dump_signal_info_error) { ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG cannot get siginfo: Bad address\n\n", getFakeLogPrint().c_str()); ASSERT_STREQ("", amfd_data_.c_str()); } TEST_F(TombstoneTest, dump_log_file_error) { Loading @@ -596,4 +620,14 @@ TEST_F(TombstoneTest, dump_log_file_error) { ASSERT_STREQ("", getFakeLogBuf().c_str()); ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n", getFakeLogPrint().c_str()); ASSERT_STREQ("", amfd_data_.c_str()); } TEST_F(TombstoneTest, dump_header_info) { dump_header_info(&log_); std::string expected = "Build fingerprint: 'unknown'\nRevision: 'unknown'\n"; expected += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING); ASSERT_STREQ(expected.c_str(), amfd_data_.c_str()); }