Loading debuggerd/debuggerd_test.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -354,7 +354,14 @@ TEST_F(CrasherTest, abort_message) { int intercept_result; unique_fd output_fd; StartProcess([]() { android_set_abort_message("abort message goes here"); // Arrived at experimentally; // logd truncates at 4062. // strlen("Abort message: ''") is 17. // That's 4045, but we also want a NUL. char buf[4045 + 1]; memset(buf, 'x', sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; android_set_abort_message(buf); abort(); }); StartIntercept(&output_fd); Loading @@ -366,7 +373,7 @@ TEST_F(CrasherTest, abort_message) { std::string result; ConsumeFd(std::move(output_fd), &result); ASSERT_MATCH(result, R"(Abort message: 'abort message goes here')"); ASSERT_MATCH(result, R"(Abort message: 'x{4045}')"); } TEST_F(CrasherTest, abort_message_backtrace) { Loading debuggerd/libdebuggerd/tombstone.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -239,19 +239,23 @@ static void dump_abort_message(log_t* log, Memory* process_memory, uint64_t addr return; } char msg[512]; if (length >= sizeof(msg)) { _LOG(log, logtype::HEADER, "Abort message too long: claimed length = %zd\n", length); // The length field includes the length of the length field itself. if (length < sizeof(size_t)) { _LOG(log, logtype::HEADER, "Abort message header malformed: claimed length = %zd\n", length); return; } if (!process_memory->ReadFully(address + sizeof(length), msg, length)) { length -= sizeof(size_t); std::vector<char> msg(length); if (!process_memory->ReadFully(address + sizeof(length), &msg[0], length)) { _LOG(log, logtype::HEADER, "Failed to read abort message: %s\n", strerror(errno)); return; } // The abort message should be null terminated already, but just in case... msg[length] = '\0'; _LOG(log, logtype::HEADER, "Abort message: '%s'\n", msg); _LOG(log, logtype::HEADER, "Abort message: '%s'\n", &msg[0]); } static void dump_all_maps(log_t* log, BacktraceMap* map, Memory* process_memory, uint64_t addr) { Loading debuggerd/libdebuggerd/utility.cpp +9 −12 Original line number Diff line number Diff line Loading @@ -74,25 +74,22 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { && (log->crashed_tid == log->current_tid); static bool write_to_kmsg = should_write_to_kmsg(); char buf[512]; std::string msg; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); android::base::StringAppendV(&msg, fmt, ap); va_end(ap); size_t len = strlen(buf); if (len <= 0) { return; } if (msg.empty()) return; if (write_to_tombstone) { TEMP_FAILURE_RETRY(write(log->tfd, buf, len)); TEMP_FAILURE_RETRY(write(log->tfd, msg.c_str(), msg.size())); } if (write_to_logcat) { __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_FATAL, LOG_TAG, buf); __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_FATAL, LOG_TAG, msg.c_str()); if (log->amfd_data != nullptr) { *log->amfd_data += buf; *log->amfd_data += msg; } if (write_to_kmsg) { Loading @@ -100,11 +97,11 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { if (kmsg_fd.get() >= 0) { // Our output might contain newlines which would otherwise be handled by the android logger. // Split the lines up ourselves before sending to the kernel logger. if (buf[len - 1] == '\n') { buf[len - 1] = '\0'; if (msg.back() == '\n') { msg.back() = '\0'; } std::vector<std::string> fragments = android::base::Split(buf, "\n"); std::vector<std::string> fragments = android::base::Split(msg, "\n"); for (const std::string& fragment : fragments) { static constexpr char prefix[] = "<3>DEBUG: "; struct iovec iov[3]; Loading Loading
debuggerd/debuggerd_test.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -354,7 +354,14 @@ TEST_F(CrasherTest, abort_message) { int intercept_result; unique_fd output_fd; StartProcess([]() { android_set_abort_message("abort message goes here"); // Arrived at experimentally; // logd truncates at 4062. // strlen("Abort message: ''") is 17. // That's 4045, but we also want a NUL. char buf[4045 + 1]; memset(buf, 'x', sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; android_set_abort_message(buf); abort(); }); StartIntercept(&output_fd); Loading @@ -366,7 +373,7 @@ TEST_F(CrasherTest, abort_message) { std::string result; ConsumeFd(std::move(output_fd), &result); ASSERT_MATCH(result, R"(Abort message: 'abort message goes here')"); ASSERT_MATCH(result, R"(Abort message: 'x{4045}')"); } TEST_F(CrasherTest, abort_message_backtrace) { Loading
debuggerd/libdebuggerd/tombstone.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -239,19 +239,23 @@ static void dump_abort_message(log_t* log, Memory* process_memory, uint64_t addr return; } char msg[512]; if (length >= sizeof(msg)) { _LOG(log, logtype::HEADER, "Abort message too long: claimed length = %zd\n", length); // The length field includes the length of the length field itself. if (length < sizeof(size_t)) { _LOG(log, logtype::HEADER, "Abort message header malformed: claimed length = %zd\n", length); return; } if (!process_memory->ReadFully(address + sizeof(length), msg, length)) { length -= sizeof(size_t); std::vector<char> msg(length); if (!process_memory->ReadFully(address + sizeof(length), &msg[0], length)) { _LOG(log, logtype::HEADER, "Failed to read abort message: %s\n", strerror(errno)); return; } // The abort message should be null terminated already, but just in case... msg[length] = '\0'; _LOG(log, logtype::HEADER, "Abort message: '%s'\n", msg); _LOG(log, logtype::HEADER, "Abort message: '%s'\n", &msg[0]); } static void dump_all_maps(log_t* log, BacktraceMap* map, Memory* process_memory, uint64_t addr) { Loading
debuggerd/libdebuggerd/utility.cpp +9 −12 Original line number Diff line number Diff line Loading @@ -74,25 +74,22 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { && (log->crashed_tid == log->current_tid); static bool write_to_kmsg = should_write_to_kmsg(); char buf[512]; std::string msg; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); android::base::StringAppendV(&msg, fmt, ap); va_end(ap); size_t len = strlen(buf); if (len <= 0) { return; } if (msg.empty()) return; if (write_to_tombstone) { TEMP_FAILURE_RETRY(write(log->tfd, buf, len)); TEMP_FAILURE_RETRY(write(log->tfd, msg.c_str(), msg.size())); } if (write_to_logcat) { __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_FATAL, LOG_TAG, buf); __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_FATAL, LOG_TAG, msg.c_str()); if (log->amfd_data != nullptr) { *log->amfd_data += buf; *log->amfd_data += msg; } if (write_to_kmsg) { Loading @@ -100,11 +97,11 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { if (kmsg_fd.get() >= 0) { // Our output might contain newlines which would otherwise be handled by the android logger. // Split the lines up ourselves before sending to the kernel logger. if (buf[len - 1] == '\n') { buf[len - 1] = '\0'; if (msg.back() == '\n') { msg.back() = '\0'; } std::vector<std::string> fragments = android::base::Split(buf, "\n"); std::vector<std::string> fragments = android::base::Split(msg, "\n"); for (const std::string& fragment : fragments) { static constexpr char prefix[] = "<3>DEBUG: "; struct iovec iov[3]; Loading