debuggerd: store commandline instead of process name.
Bug: http://b/180605583 Test: debuggerd_test Change-Id: I018d399a5460f357766dc1b429f645f78fe88565
This commit is contained in:
parent
5d5e16db57
commit
31348a74e0
11 changed files with 63 additions and 23 deletions
|
@ -96,7 +96,7 @@ static std::string get_wchan_data(pid_t pid) {
|
|||
|
||||
if (std::string str = data.str(); !str.empty()) {
|
||||
buffer << "\n----- Waiting Channels: pid " << pid << " at " << get_timestamp() << " -----\n"
|
||||
<< "Cmd line: " << get_process_name(pid) << "\n";
|
||||
<< "Cmd line: " << android::base::Join(get_command_line(pid), " ") << "\n";
|
||||
buffer << "\n" << str << "\n";
|
||||
buffer << "----- end " << std::to_string(pid) << " -----\n";
|
||||
buffer << "\n";
|
||||
|
|
|
@ -450,9 +450,6 @@ int main(int argc, char** argv) {
|
|||
// unwind, do not make this too small. b/62828735
|
||||
alarm(30 * android::base::HwTimeoutMultiplier());
|
||||
|
||||
// Get the process name (aka cmdline).
|
||||
std::string process_name = get_process_name(g_target_thread);
|
||||
|
||||
// Collect the list of open files.
|
||||
OpenFilesList open_files;
|
||||
{
|
||||
|
@ -489,7 +486,6 @@ int main(int argc, char** argv) {
|
|||
info.pid = target_process;
|
||||
info.tid = thread;
|
||||
info.uid = getuid();
|
||||
info.process_name = process_name;
|
||||
info.thread_name = get_thread_name(thread);
|
||||
|
||||
unique_fd attr_fd(openat(target_proc_fd, "attr/current", O_RDONLY | O_CLOEXEC));
|
||||
|
@ -517,6 +513,8 @@ int main(int argc, char** argv) {
|
|||
ReadCrashInfo(input_pipe, &siginfo, &info.registers, &process_info);
|
||||
info.siginfo = &siginfo;
|
||||
info.signo = info.siginfo->si_signo;
|
||||
|
||||
info.command_line = get_command_line(g_target_thread);
|
||||
} else {
|
||||
info.registers.reset(unwindstack::Regs::RemoteGet(thread));
|
||||
if (!info.registers) {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <android-base/strings.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <log/log.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
@ -42,11 +43,12 @@
|
|||
#include "libdebuggerd/utility.h"
|
||||
#include "util.h"
|
||||
|
||||
static void dump_process_header(log_t* log, pid_t pid, const char* process_name) {
|
||||
static void dump_process_header(log_t* log, pid_t pid,
|
||||
const std::vector<std::string>& command_line) {
|
||||
_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);
|
||||
if (!command_line.empty()) {
|
||||
_LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", android::base::Join(command_line, " ").c_str());
|
||||
}
|
||||
_LOG(log, logtype::BACKTRACE, "ABI: '%s'\n", ABI_STRING);
|
||||
}
|
||||
|
@ -89,7 +91,7 @@ void dump_backtrace(android::base::unique_fd output_fd, unwindstack::Unwinder* u
|
|||
return;
|
||||
}
|
||||
|
||||
dump_process_header(&log, target->second.pid, target->second.process_name.c_str());
|
||||
dump_process_header(&log, target->second.pid, target->second.command_line);
|
||||
|
||||
dump_backtrace_thread(output_fd.get(), unwinder, target->second);
|
||||
for (const auto& [tid, info] : thread_info) {
|
||||
|
@ -107,7 +109,7 @@ void dump_backtrace_header(int output_fd) {
|
|||
log.amfd_data = nullptr;
|
||||
|
||||
pid_t pid = getpid();
|
||||
dump_process_header(&log, pid, get_process_name(pid).c_str());
|
||||
dump_process_header(&log, pid, get_command_line(pid));
|
||||
}
|
||||
|
||||
void dump_backtrace_footer(int output_fd) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <unwindstack/Regs.h>
|
||||
|
||||
|
@ -32,13 +33,14 @@ struct ThreadInfo {
|
|||
|
||||
pid_t pid;
|
||||
|
||||
std::string process_name;
|
||||
std::vector<std::string> command_line;
|
||||
std::string selinux_label;
|
||||
|
||||
int signo = 0;
|
||||
siginfo_t* siginfo = nullptr;
|
||||
};
|
||||
|
||||
// This struct is written into a pipe from inside the crashing process.
|
||||
struct ProcessInfo {
|
||||
uintptr_t abort_msg_address = 0;
|
||||
uintptr_t fdsan_table_address = 0;
|
||||
|
|
|
@ -350,11 +350,11 @@ TEST_F(TombstoneTest, dump_header_info) {
|
|||
}
|
||||
|
||||
TEST_F(TombstoneTest, dump_thread_info_uid) {
|
||||
dump_thread_info(&log_, ThreadInfo{.uid = 1,
|
||||
.tid = 3,
|
||||
.thread_name = "some_thread",
|
||||
.pid = 2,
|
||||
.process_name = "some_process"});
|
||||
std::vector<std::string> cmdline = {"some_process"};
|
||||
dump_thread_info(
|
||||
&log_,
|
||||
ThreadInfo{
|
||||
.uid = 1, .tid = 3, .thread_name = "some_thread", .pid = 2, .command_line = cmdline});
|
||||
std::string expected = "pid: 2, tid: 3, name: some_thread >>> some_process <<<\nuid: 1\n";
|
||||
ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
|
||||
}
|
||||
|
|
|
@ -182,8 +182,13 @@ static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) {
|
|||
// 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;
|
||||
|
||||
const char* process_name = "<unknown>";
|
||||
if (!thread_info.command_line.empty()) {
|
||||
process_name = thread_info.command_line[0].c_str();
|
||||
}
|
||||
|
||||
_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());
|
||||
thread_info.tid, thread_info.thread_name.c_str(), process_name);
|
||||
_LOG(log, logtype::HEADER, "uid: %d\n", thread_info.uid);
|
||||
if (thread_info.tagged_addr_ctrl != -1) {
|
||||
_LOG(log, logtype::HEADER, "tagged_addr_ctrl: %016lx\n", thread_info.tagged_addr_ctrl);
|
||||
|
@ -567,7 +572,7 @@ void engrave_tombstone_ucontext(int tombstone_fd, int proto_fd, uint64_t abort_m
|
|||
log.amfd_data = nullptr;
|
||||
|
||||
std::string thread_name = get_thread_name(tid);
|
||||
std::string process_name = get_process_name(pid);
|
||||
std::vector<std::string> command_line = get_command_line(pid);
|
||||
|
||||
std::unique_ptr<unwindstack::Regs> regs(
|
||||
unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
|
||||
|
@ -582,7 +587,7 @@ void engrave_tombstone_ucontext(int tombstone_fd, int proto_fd, uint64_t abort_m
|
|||
.tid = tid,
|
||||
.thread_name = std::move(thread_name),
|
||||
.pid = pid,
|
||||
.process_name = std::move(process_name),
|
||||
.command_line = std::move(command_line),
|
||||
.selinux_label = std::move(selinux_label),
|
||||
.siginfo = siginfo,
|
||||
};
|
||||
|
|
|
@ -562,7 +562,11 @@ void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::Unwinder* unwind
|
|||
result.set_uid(main_thread.uid);
|
||||
result.set_selinux_label(main_thread.selinux_label);
|
||||
|
||||
result.set_process_name(main_thread.process_name);
|
||||
auto cmd_line = result.mutable_command_line();
|
||||
for (const auto& arg : main_thread.command_line) {
|
||||
*cmd_line->Add() = arg;
|
||||
}
|
||||
|
||||
if (!main_thread.siginfo) {
|
||||
async_safe_fatal("siginfo missing");
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <async_safe/log.h>
|
||||
|
||||
|
@ -71,8 +72,13 @@ static int pointer_width(const Tombstone& tombstone) {
|
|||
|
||||
static void print_thread_header(CallbackType callback, const Tombstone& tombstone,
|
||||
const Thread& thread, bool should_log) {
|
||||
const char* process_name = "<unknown>";
|
||||
if (!tombstone.command_line().empty()) {
|
||||
process_name = tombstone.command_line()[0].c_str();
|
||||
CB(should_log, "Cmdline: %s", android::base::Join(tombstone.command_line(), " ").c_str());
|
||||
}
|
||||
CB(should_log, "pid: %d, tid: %d, name: %s >>> %s <<<", tombstone.pid(), thread.id(),
|
||||
thread.name().c_str(), tombstone.process_name().c_str());
|
||||
thread.name().c_str(), process_name);
|
||||
CB(should_log, "uid: %d", tombstone.uid());
|
||||
if (thread.tagged_addr_ctrl() != -1) {
|
||||
CB(should_log, "tagged_addr_ctrl: %016" PRIx64, thread.tagged_addr_ctrl());
|
||||
|
|
|
@ -17,7 +17,7 @@ message Tombstone {
|
|||
uint32 uid = 7;
|
||||
string selinux_label = 8;
|
||||
|
||||
string process_name = 9;
|
||||
repeated string command_line = 9;
|
||||
|
||||
// Process uptime in seconds.
|
||||
uint32 process_uptime = 20;
|
||||
|
|
|
@ -26,10 +26,31 @@
|
|||
#include <android-base/strings.h>
|
||||
#include "protocol.h"
|
||||
|
||||
std::vector<std::string> get_command_line(pid_t pid) {
|
||||
std::vector<std::string> result;
|
||||
|
||||
std::string cmdline;
|
||||
android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/cmdline", pid), &cmdline);
|
||||
|
||||
auto it = cmdline.cbegin();
|
||||
while (it != cmdline.cend()) {
|
||||
// string::iterator is a wrapped type, not a raw char*.
|
||||
auto terminator = std::find(it, cmdline.cend(), '\0');
|
||||
result.emplace_back(it, terminator);
|
||||
it = std::find_if(terminator, cmdline.cend(), [](char c) { return c != '\0'; });
|
||||
}
|
||||
if (result.empty()) {
|
||||
result.emplace_back("<unknown>");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string get_process_name(pid_t pid) {
|
||||
std::string result = "<unknown>";
|
||||
android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/cmdline", pid), &result);
|
||||
return result;
|
||||
// We only want the name, not the whole command line, so truncate at the first NUL.
|
||||
return result.c_str();
|
||||
}
|
||||
|
||||
std::string get_thread_name(pid_t tid) {
|
||||
|
|
|
@ -17,10 +17,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
std::vector<std::string> get_command_line(pid_t pid);
|
||||
std::string get_process_name(pid_t pid);
|
||||
std::string get_thread_name(pid_t tid);
|
||||
|
||||
|
|
Loading…
Reference in a new issue