libdebuggerd: fix process uptime.

I was here because we have a case where timeout(1) kills logcat, but
debuggerd alleges that the process that was killed had started less than
a second ago. I'm not sure this is the problem there, but I did notice
that far too many tombstones were claiming improbably short process
uptimes. It turns out that the code was measuring the *thread* uptime,
not the *process* uptime.

Also simplify the code a bit by switching to sysinfo(2) rather than
reading a file.

Test: manual, plus the existing unit test
Change-Id: Ie2810b1d5777ad9182be92bfb3f60795dc978b24
This commit is contained in:
Elliott Hughes 2021-09-21 12:20:53 -07:00
parent 3275d3eeec
commit 32d3cdda22
6 changed files with 18 additions and 24 deletions

View file

@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/sysinfo.h>
#include <time.h>
#include <memory>
@ -596,14 +597,6 @@ static void dump_tags_around_fault_addr(Signal* signal, const Tombstone& tombsto
}
}
static std::optional<uint64_t> read_uptime_secs() {
std::string uptime;
if (!android::base::ReadFileToString("/proc/uptime", &uptime)) {
return {};
}
return strtoll(uptime.c_str(), nullptr, 10);
}
void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
const std::map<pid_t, ThreadInfo>& threads, pid_t target_thread,
const ProcessInfo& process_info, const OpenFilesList* open_files) {
@ -614,28 +607,24 @@ void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::Unwinder* unwind
result.set_revision(android::base::GetProperty("ro.revision", "unknown"));
result.set_timestamp(get_timestamp());
std::optional<uint64_t> system_uptime = read_uptime_secs();
if (system_uptime) {
android::procinfo::ProcessInfo proc_info;
std::string error;
if (android::procinfo::GetProcessInfo(target_thread, &proc_info, &error)) {
uint64_t starttime = proc_info.starttime / sysconf(_SC_CLK_TCK);
result.set_process_uptime(*system_uptime - starttime);
} else {
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "failed to read process info: %s",
error.c_str());
}
} else {
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "failed to read /proc/uptime: %s",
strerror(errno));
}
const ThreadInfo& main_thread = threads.at(target_thread);
result.set_pid(main_thread.pid);
result.set_tid(main_thread.tid);
result.set_uid(main_thread.uid);
result.set_selinux_label(main_thread.selinux_label);
struct sysinfo si;
sysinfo(&si);
android::procinfo::ProcessInfo proc_info;
std::string error;
if (android::procinfo::GetProcessInfo(main_thread.pid, &proc_info, &error)) {
uint64_t starttime = proc_info.starttime / sysconf(_SC_CLK_TCK);
result.set_process_uptime(si.uptime - starttime);
} else {
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "failed to read process info: %s",
error.c_str());
}
auto cmd_line = result.mutable_command_line();
for (const auto& arg : main_thread.command_line) {
*cmd_line->Add() = arg;

View file

@ -20,6 +20,7 @@ getdents64: 1
faccessat: 1
recvmsg: 1
recvfrom: 1
sysinfo: 1
process_vm_readv: 1
tgkill: 1
rt_sigprocmask: 1

View file

@ -19,6 +19,7 @@ getdents64: 1
faccessat: 1
recvmsg: 1
recvfrom: 1
sysinfo: 1
process_vm_readv: 1
tgkill: 1
rt_sigprocmask: 1

View file

@ -25,6 +25,7 @@ getdents64: 1
faccessat: 1
recvmsg: 1
recvfrom: 1
sysinfo: 1
process_vm_readv: 1

View file

@ -20,6 +20,7 @@ getdents64: 1
faccessat: 1
recvmsg: 1
recvfrom: 1
sysinfo: 1
process_vm_readv: 1
tgkill: 1
rt_sigprocmask: 1

View file

@ -19,6 +19,7 @@ getdents64: 1
faccessat: 1
recvmsg: 1
recvfrom: 1
sysinfo: 1
process_vm_readv: 1
tgkill: 1
rt_sigprocmask: 1