libdebuggerd: store process uptime.
Application developers would like to know how long their process has been alive for to distinguish between crashes that happen immediately upon startup and crashes in regular operation. Test: manual Change-Id: Ia31eeadfcced358b478c7a7c7bb2e8a0252e30f4
This commit is contained in:
parent
8b0a9e06ba
commit
dbb83de0d5
4 changed files with 33 additions and 1 deletions
|
|
@ -238,6 +238,7 @@ cc_library_static {
|
|||
"gwp_asan_crash_handler",
|
||||
"libscudo",
|
||||
"libtombstone_proto",
|
||||
"libprocinfo",
|
||||
"libprotobuf-cpp-lite",
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,12 @@
|
|||
#include <time.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <async_safe/log.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
|
|
@ -44,6 +46,7 @@
|
|||
#include <log/logprint.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
|
||||
#include <procinfo/process.h>
|
||||
#include <unwindstack/Maps.h>
|
||||
#include <unwindstack/Memory.h>
|
||||
#include <unwindstack/Regs.h>
|
||||
|
|
@ -422,6 +425,14 @@ static void dump_logcat(Tombstone* tombstone, pid_t pid) {
|
|||
dump_log_file(tombstone, "main", pid);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -432,6 +443,22 @@ 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);
|
||||
|
|
|
|||
|
|
@ -313,6 +313,7 @@ bool tombstone_proto_to_text(const Tombstone& tombstone, CallbackType callback)
|
|||
CBL("Revision: '%s'", tombstone.revision().c_str());
|
||||
CBL("ABI: '%s'", abi_string(tombstone));
|
||||
CBL("Timestamp: %s", tombstone.timestamp().c_str());
|
||||
CBL("Process uptime: %ds", tombstone.process_uptime());
|
||||
|
||||
// Process header
|
||||
const auto& threads = tombstone.threads();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ message Tombstone {
|
|||
|
||||
string process_name = 9;
|
||||
|
||||
// Process uptime in seconds.
|
||||
uint32 process_uptime = 20;
|
||||
|
||||
Signal signal_info = 10;
|
||||
string abort_message = 14;
|
||||
Cause cause = 15;
|
||||
|
|
@ -28,7 +31,7 @@ message Tombstone {
|
|||
repeated LogBuffer log_buffers = 18;
|
||||
repeated FD open_fds = 19;
|
||||
|
||||
reserved 20 to 999;
|
||||
reserved 21 to 999;
|
||||
}
|
||||
|
||||
enum Architecture {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue