diff --git a/debuggerd/client/debuggerd_client.cpp b/debuggerd/client/debuggerd_client.cpp index 5c027387c..6bfb5f2c2 100644 --- a/debuggerd/client/debuggerd_client.cpp +++ b/debuggerd/client/debuggerd_client.cpp @@ -70,36 +70,6 @@ static void populate_timeval(struct timeval* tv, const Duration& duration) { tv->tv_usec = static_cast(microseconds.count()); } -static void get_wchan_header(pid_t pid, std::stringstream& buffer) { - struct tm now; - time_t t = time(nullptr); - localtime_r(&t, &now); - char timestamp[32]; - strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &now); - std::string time_now(timestamp); - - std::string path = "/proc/" + std::to_string(pid) + "/cmdline"; - - char proc_name_buf[1024]; - const char* proc_name = nullptr; - std::unique_ptr fp(fopen(path.c_str(), "r"), &fclose); - - if (fp) { - proc_name = fgets(proc_name_buf, sizeof(proc_name_buf), fp.get()); - } - - if (!proc_name) { - proc_name = ""; - } - - buffer << "\n----- Waiting Channels: pid " << pid << " at " << time_now << " -----\n" - << "Cmd line: " << proc_name << "\n"; -} - -static void get_wchan_footer(pid_t pid, std::stringstream& buffer) { - buffer << "----- end " << std::to_string(pid) << " -----\n"; -} - /** * Returns the wchan data for each thread in the process, * or empty string if unable to obtain any data. @@ -125,9 +95,10 @@ static std::string get_wchan_data(pid_t pid) { } if (std::string str = data.str(); !str.empty()) { - get_wchan_header(pid, buffer); + buffer << "\n----- Waiting Channels: pid " << pid << " at " << get_timestamp() << " -----\n" + << "Cmd line: " << get_process_name(pid) << "\n"; buffer << "\n" << str << "\n"; - get_wchan_footer(pid, buffer); + buffer << "----- end " << std::to_string(pid) << " -----\n"; buffer << "\n"; } diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp index c60697099..f5a873c4d 100644 --- a/debuggerd/libdebuggerd/backtrace.cpp +++ b/debuggerd/libdebuggerd/backtrace.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -40,14 +39,10 @@ #include "libdebuggerd/types.h" #include "libdebuggerd/utility.h" +#include "util.h" static void dump_process_header(log_t* log, pid_t pid, const char* process_name) { - time_t t = time(NULL); - struct tm tm; - localtime_r(&t, &tm); - char timestr[64]; - strftime(timestr, sizeof(timestr), "%F %T", &tm); - _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr); + _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, get_timestamp().c_str()); if (process_name) { _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", process_name); @@ -106,9 +101,8 @@ void dump_backtrace_header(int output_fd) { log.tfd = output_fd; log.amfd_data = nullptr; - char process_name[128]; - read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), ""); - dump_process_header(&log, getpid(), process_name); + pid_t pid = getpid(); + dump_process_header(&log, pid, get_process_name(pid).c_str()); } void dump_backtrace_footer(int output_fd) { diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h index 7bfcf5d6e..76155b183 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h @@ -83,8 +83,6 @@ void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* pref void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const std::string&); -void read_with_default(const char* path, char* buf, size_t len, const char* default_value); - void drop_capabilities(); bool signal_has_sender(const siginfo_t*, pid_t caller_pid); diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp index aec8c6030..b42d70ce8 100644 --- a/debuggerd/libdebuggerd/test/tombstone_test.cpp +++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp @@ -359,13 +359,6 @@ TEST_F(TombstoneTest, dump_thread_info_uid) { ASSERT_STREQ(expected.c_str(), amfd_data_.c_str()); } -TEST_F(TombstoneTest, dump_timestamp) { - setenv("TZ", "UTC", 1); - tzset(); - dump_timestamp(&log_, 0); - ASSERT_STREQ("Timestamp: 1970-01-01 00:00:00+0000\n", amfd_data_.c_str()); -} - class GwpAsanCrashDataTest : public GwpAsanCrashData { public: GwpAsanCrashDataTest( diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index ab65dd15a..face02bd7 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp @@ -58,6 +58,7 @@ #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" @@ -80,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; @@ -507,10 +499,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(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); + tm tm; + localtime_r(&sec, &tm); + strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", &tm); char* msg = log_entry.msg(); if (msg == nullptr) { @@ -571,23 +562,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), ""); - read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), ""); + std::string thread_name = get_thread_name(tid); + std::string process_name = get_process_name(pid); std::unique_ptr regs( unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext)); std::map 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, }; @@ -606,8 +594,8 @@ void engrave_tombstone(unique_fd output_fd, unwindstack::Unwinder* unwinder, const std::map& threads, pid_t target_thread, const ProcessInfo& process_info, OpenFilesList* open_files, std::string* amfd_data) { - // don't copy log messages to tombstone unless this is a dev device - bool want_logs = android::base::GetBoolProperty("ro.debuggable", false); + // 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; @@ -617,7 +605,7 @@ 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()) { diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp index c8032eb90..f43092c21 100644 --- a/debuggerd/libdebuggerd/utility.cpp +++ b/debuggerd/libdebuggerd/utility.cpp @@ -239,23 +239,6 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const s } } -void read_with_default(const char* path, char* buf, size_t len, const char* default_value) { - unique_fd fd(open(path, O_RDONLY | O_CLOEXEC)); - if (fd != -1) { - int rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, len - 1)); - if (rc != -1) { - buf[rc] = '\0'; - - // Trim trailing newlines. - if (rc > 0 && buf[rc - 1] == '\n') { - buf[rc - 1] = '\0'; - } - return; - } - } - strcpy(buf, default_value); -} - void drop_capabilities() { __user_cap_header_struct capheader; memset(&capheader, 0, sizeof(capheader)); diff --git a/debuggerd/util.cpp b/debuggerd/util.cpp index a37b3b93b..9d09210f5 100644 --- a/debuggerd/util.cpp +++ b/debuggerd/util.cpp @@ -17,6 +17,7 @@ #include "util.h" #include +#include #include #include @@ -38,3 +39,19 @@ std::string get_thread_name(pid_t tid) { android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/comm", tid), &result); return android::base::Trim(result); } + +std::string get_timestamp() { + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + + tm tm; + localtime_r(&ts.tv_sec, &tm); + + char buf[strlen("1970-01-01 00:00:00.123456789+0830") + 1]; + char* s = buf; + size_t sz = sizeof(buf), n; + n = strftime(s, sz, "%F %H:%M", &tm), s += n, sz -= n; + n = snprintf(s, sz, ":%02d.%09ld", tm.tm_sec, ts.tv_nsec), s += n, sz -= n; + n = strftime(s, sz, "%z", &tm), s += n, sz -= n; + return buf; +} diff --git a/debuggerd/util.h b/debuggerd/util.h index e96442360..07e7e992c 100644 --- a/debuggerd/util.h +++ b/debuggerd/util.h @@ -23,3 +23,5 @@ std::string get_process_name(pid_t pid); std::string get_thread_name(pid_t tid); + +std::string get_timestamp();