summaryrefslogtreecommitdiff
path: root/debuggerd/libdebuggerd/tombstone.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'debuggerd/libdebuggerd/tombstone.cpp')
-rw-r--r--debuggerd/libdebuggerd/tombstone.cpp131
1 files changed, 53 insertions, 78 deletions
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index fd52e81137..7af99c94c1 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -43,6 +43,7 @@
#include <android-base/unique_fd.h>
#include <android/log.h>
#include <log/log.h>
+#include <log/log_read.h>
#include <log/logprint.h>
#include <private/android_filesystem_config.h>
#include <unwindstack/DexFiles.h>
@@ -55,7 +56,9 @@
#include "libdebuggerd/backtrace.h"
#include "libdebuggerd/gwp_asan.h"
#include "libdebuggerd/open_files_list.h"
+#include "libdebuggerd/scudo.h"
#include "libdebuggerd/utility.h"
+#include "util.h"
#include "gwp_asan/common.h"
#include "gwp_asan/crash_handler.h"
@@ -78,15 +81,6 @@ static void dump_header_info(log_t* log) {
_LOG(log, logtype::HEADER, "ABI: '%s'\n", ABI_STRING);
}
-static void dump_timestamp(log_t* log, time_t time) {
- struct tm tm;
- localtime_r(&time, &tm);
-
- char buf[strlen("1970-01-01 00:00:00+0830") + 1];
- strftime(buf, sizeof(buf), "%F %T%z", &tm);
- _LOG(log, logtype::HEADER, "Timestamp: %s\n", buf);
-}
-
static std::string get_stack_overflow_cause(uint64_t fault_addr, uint64_t sp,
unwindstack::Maps* maps) {
static constexpr uint64_t kMaxDifferenceBytes = 256;
@@ -154,16 +148,16 @@ static void dump_probable_cause(log_t* log, const siginfo_t* si, unwindstack::Ma
}
static void dump_signal_info(log_t* log, const ThreadInfo& thread_info,
- unwindstack::Memory* process_memory) {
+ const ProcessInfo& process_info, unwindstack::Memory* process_memory) {
char addr_desc[64]; // ", fault addr 0x1234"
- if (signal_has_si_addr(thread_info.siginfo)) {
- void* addr = thread_info.siginfo->si_addr;
+ if (process_info.has_fault_address) {
+ size_t addr = process_info.fault_address;
if (thread_info.siginfo->si_signo == SIGILL) {
uint32_t instruction = {};
- process_memory->Read(reinterpret_cast<uint64_t>(addr), &instruction, sizeof(instruction));
- snprintf(addr_desc, sizeof(addr_desc), "%p (*pc=%#08x)", addr, instruction);
+ process_memory->Read(addr, &instruction, sizeof(instruction));
+ snprintf(addr_desc, sizeof(addr_desc), "0x%zx (*pc=%#08x)", addr, instruction);
} else {
- snprintf(addr_desc, sizeof(addr_desc), "%p", addr);
+ snprintf(addr_desc, sizeof(addr_desc), "0x%zx", addr);
}
} else {
snprintf(addr_desc, sizeof(addr_desc), "--------");
@@ -180,12 +174,8 @@ static void dump_signal_info(log_t* log, const ThreadInfo& thread_info,
}
static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) {
- // Blacklist logd, logd.reader, logd.writer, logd.auditd, logd.control ...
- // TODO: Why is this controlled by thread name?
- if (thread_info.thread_name == "logd" ||
- android::base::StartsWith(thread_info.thread_name, "logd.")) {
- log->should_retrieve_logcat = false;
- }
+ // Don't try to collect logs from the threads that implement the logging system itself.
+ if (thread_info.uid == AID_LOGD) log->should_retrieve_logcat = false;
_LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s >>> %s <<<\n", thread_info.pid,
thread_info.tid, thread_info.thread_name.c_str(), thread_info.process_name.c_str());
@@ -376,8 +366,7 @@ void dump_memory_and_code(log_t* log, unwindstack::Maps* maps, unwindstack::Memo
}
static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const ThreadInfo& thread_info,
- uint64_t abort_msg_address, bool primary_thread,
- const GwpAsanCrashData& gwp_asan_crash_data) {
+ const ProcessInfo& process_info, bool primary_thread) {
log->current_tid = thread_info.tid;
if (!primary_thread) {
_LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
@@ -385,18 +374,27 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa
dump_thread_info(log, thread_info);
if (thread_info.siginfo) {
- dump_signal_info(log, thread_info, unwinder->GetProcessMemory().get());
+ dump_signal_info(log, thread_info, process_info, unwinder->GetProcessMemory().get());
}
- if (primary_thread && gwp_asan_crash_data.CrashIsMine()) {
- gwp_asan_crash_data.DumpCause(log);
- } else if (thread_info.siginfo) {
+ std::unique_ptr<GwpAsanCrashData> gwp_asan_crash_data;
+ std::unique_ptr<ScudoCrashData> scudo_crash_data;
+ if (primary_thread) {
+ gwp_asan_crash_data = std::make_unique<GwpAsanCrashData>(unwinder->GetProcessMemory().get(),
+ process_info, thread_info);
+ scudo_crash_data =
+ std::make_unique<ScudoCrashData>(unwinder->GetProcessMemory().get(), process_info);
+ }
+
+ if (primary_thread && gwp_asan_crash_data->CrashIsMine()) {
+ gwp_asan_crash_data->DumpCause(log);
+ } else if (thread_info.siginfo && !(primary_thread && scudo_crash_data->CrashIsMine())) {
dump_probable_cause(log, thread_info.siginfo, unwinder->GetMaps(),
thread_info.registers.get());
}
if (primary_thread) {
- dump_abort_message(log, unwinder->GetProcessMemory().get(), abort_msg_address);
+ dump_abort_message(log, unwinder->GetProcessMemory().get(), process_info.abort_msg_address);
}
dump_registers(log, thread_info.registers.get());
@@ -413,14 +411,16 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa
}
if (primary_thread) {
- if (gwp_asan_crash_data.HasDeallocationTrace()) {
- gwp_asan_crash_data.DumpDeallocationTrace(log, unwinder);
+ if (gwp_asan_crash_data->HasDeallocationTrace()) {
+ gwp_asan_crash_data->DumpDeallocationTrace(log, unwinder);
}
- if (gwp_asan_crash_data.HasAllocationTrace()) {
- gwp_asan_crash_data.DumpAllocationTrace(log, unwinder);
+ if (gwp_asan_crash_data->HasAllocationTrace()) {
+ gwp_asan_crash_data->DumpAllocationTrace(log, unwinder);
}
+ scudo_crash_data->DumpCause(log, unwinder);
+
unwindstack::Maps* maps = unwinder->GetMaps();
dump_memory_and_code(log, maps, unwinder->GetProcessMemory().get(),
thread_info.registers.get());
@@ -442,8 +442,6 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa
// that don't match the specified pid, and writes them to the tombstone file.
//
// If "tail" is non-zero, log the last "tail" number of lines.
-static EventTagMap* g_eventTagMap = NULL;
-
static void dump_log_file(log_t* log, pid_t pid, const char* filename, unsigned int tail) {
bool first = true;
logger_list* logger_list;
@@ -452,8 +450,8 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, unsigned
return;
}
- logger_list = android_logger_list_open(
- android_name_to_log_id(filename), ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tail, pid);
+ logger_list =
+ android_logger_list_open(android_name_to_log_id(filename), ANDROID_LOG_NONBLOCK, tail, pid);
if (!logger_list) {
ALOGE("Unable to open %s: %s\n", filename, strerror(errno));
@@ -497,25 +495,9 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, unsigned
// (although in this case the pid is redundant).
char timeBuf[32];
time_t sec = static_cast<time_t>(log_entry.entry.sec);
- struct tm tmBuf;
- struct tm* ptm;
- ptm = localtime_r(&sec, &tmBuf);
- strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
-
- if (log_entry.id() == LOG_ID_EVENTS) {
- if (!g_eventTagMap) {
- g_eventTagMap = android_openEventTagMap(nullptr);
- }
- AndroidLogEntry e;
- char buf[512];
- if (android_log_processBinaryLogBuffer(&log_entry.entry, &e, g_eventTagMap, buf,
- sizeof(buf)) == 0) {
- _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8.*s: %s\n", timeBuf,
- log_entry.entry.nsec / 1000000, log_entry.entry.pid, log_entry.entry.tid, 'I',
- (int)e.tagLen, e.tag, e.message);
- }
- continue;
- }
+ tm tm;
+ localtime_r(&sec, &tm);
+ strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", &tm);
char* msg = log_entry.msg();
if (msg == nullptr) {
@@ -576,23 +558,20 @@ void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, si
log.tfd = tombstone_fd;
log.amfd_data = nullptr;
- char thread_name[16];
- char process_name[128];
-
- read_with_default("/proc/self/comm", thread_name, sizeof(thread_name), "<unknown>");
- read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), "<unknown>");
+ std::string thread_name = get_thread_name(tid);
+ std::string process_name = get_process_name(pid);
std::unique_ptr<unwindstack::Regs> regs(
unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
std::map<pid_t, ThreadInfo> threads;
- threads[gettid()] = ThreadInfo{
+ threads[tid] = ThreadInfo{
.registers = std::move(regs),
.uid = uid,
.tid = tid,
- .thread_name = thread_name,
+ .thread_name = thread_name.c_str(),
.pid = pid,
- .process_name = process_name,
+ .process_name = process_name.c_str(),
.siginfo = siginfo,
};
@@ -601,17 +580,18 @@ void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, si
LOG(FATAL) << "Failed to init unwinder object.";
}
- engrave_tombstone(unique_fd(dup(tombstone_fd)), &unwinder, threads, tid, abort_msg_address,
- nullptr, nullptr, 0u, 0u);
+ ProcessInfo process_info;
+ process_info.abort_msg_address = abort_msg_address;
+ engrave_tombstone(unique_fd(dup(tombstone_fd)), &unwinder, threads, tid, process_info, nullptr,
+ nullptr);
}
void engrave_tombstone(unique_fd output_fd, unwindstack::Unwinder* unwinder,
const std::map<pid_t, ThreadInfo>& threads, pid_t target_thread,
- uint64_t abort_msg_address, OpenFilesList* open_files,
- std::string* amfd_data, uintptr_t gwp_asan_state_ptr,
- uintptr_t gwp_asan_metadata_ptr) {
- // don't copy log messages to tombstone unless this is a dev device
- bool want_logs = android::base::GetBoolProperty("ro.debuggable", false);
+ const ProcessInfo& process_info, OpenFilesList* open_files,
+ std::string* amfd_data) {
+ // Don't copy log messages to tombstone unless this is a development device.
+ bool want_logs = GetBoolProperty("ro.debuggable", false);
log_t log;
log.current_tid = target_thread;
@@ -621,19 +601,14 @@ void engrave_tombstone(unique_fd output_fd, unwindstack::Unwinder* unwinder,
_LOG(&log, logtype::HEADER, "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
dump_header_info(&log);
- dump_timestamp(&log, time(nullptr));
+ _LOG(&log, logtype::HEADER, "Timestamp: %s\n", get_timestamp().c_str());
auto it = threads.find(target_thread);
if (it == threads.end()) {
LOG(FATAL) << "failed to find target thread";
}
- GwpAsanCrashData gwp_asan_crash_data(unwinder->GetProcessMemory().get(),
- gwp_asan_state_ptr,
- gwp_asan_metadata_ptr, it->second);
-
- dump_thread(&log, unwinder, it->second, abort_msg_address, true,
- gwp_asan_crash_data);
+ dump_thread(&log, unwinder, it->second, process_info, true);
if (want_logs) {
dump_logs(&log, it->second.pid, 50);
@@ -644,7 +619,7 @@ void engrave_tombstone(unique_fd output_fd, unwindstack::Unwinder* unwinder,
continue;
}
- dump_thread(&log, unwinder, thread_info, 0, false, gwp_asan_crash_data);
+ dump_thread(&log, unwinder, thread_info, process_info, false);
}
if (open_files) {