libdebuggerd: add protobuf implementation.
This commit implements protobuf output for tombstones, along with a
translator that should emit bytewise identical output to the existing
tombstone dumping code, except for ancillary data from GWP-ASan and
Scudo, which haven't been implemented yet.
Test: setprop debug.debuggerd.translate.translate_proto_to_text 1 &&
/data/nativetest64/debuggerd_test/debuggerd_test
Test: for TOMBSTONE in /data/tombstones/tombstone_??; do
pbtombstone $TOMBSTONE.pb | diff $TOMBSTONE -
done
Change-Id: Ieeece6e6d1c26eb608b00ec24e2e725e161c8c92
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 4f60005..f2ff6df 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -194,6 +194,7 @@
static bool g_tombstoned_connected = false;
static unique_fd g_tombstoned_socket;
static unique_fd g_output_fd;
+static unique_fd g_proto_fd;
static void DefuseSignalHandlers() {
// Don't try to dump ourselves.
@@ -214,7 +215,7 @@
// If we abort before we get an output fd, contact tombstoned to let any
// potential listeners know that we failed.
if (!g_tombstoned_connected) {
- if (!tombstoned_connect(g_target_thread, &g_tombstoned_socket, &g_output_fd,
+ if (!tombstoned_connect(g_target_thread, &g_tombstoned_socket, &g_output_fd, &g_proto_fd,
kDebuggerdAnyIntercept)) {
// We failed to connect, not much we can do.
LOG(ERROR) << "failed to connected to tombstoned to report failure";
@@ -247,10 +248,20 @@
}
int dump_type_int;
- if (!android::base::ParseInt(argv[3], &dump_type_int, 0, 1)) {
+ if (!android::base::ParseInt(argv[3], &dump_type_int, 0)) {
LOG(FATAL) << "invalid requested dump type: " << argv[3];
}
+
*dump_type = static_cast<DebuggerdDumpType>(dump_type_int);
+ switch (*dump_type) {
+ case kDebuggerdNativeBacktrace:
+ case kDebuggerdTombstone:
+ case kDebuggerdTombstoneProto:
+ break;
+
+ default:
+ LOG(FATAL) << "invalid requested dump type: " << dump_type_int;
+ }
}
static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
@@ -477,6 +488,11 @@
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));
+ if (!android::base::ReadFdToString(attr_fd, &info.selinux_label)) {
+ PLOG(WARNING) << "failed to read selinux label";
+ }
+
if (!ptrace_interrupt(thread, &info.signo)) {
PLOG(WARNING) << "failed to ptrace interrupt thread " << thread;
ptrace(PTRACE_DETACH, thread, 0, 0);
@@ -555,8 +571,8 @@
{
ATRACE_NAME("tombstoned_connect");
LOG(INFO) << "obtaining output fd from tombstoned, type: " << dump_type;
- g_tombstoned_connected =
- tombstoned_connect(g_target_thread, &g_tombstoned_socket, &g_output_fd, dump_type);
+ g_tombstoned_connected = tombstoned_connect(g_target_thread, &g_tombstoned_socket, &g_output_fd,
+ &g_proto_fd, dump_type);
}
if (g_tombstoned_connected) {
@@ -609,8 +625,8 @@
{
ATRACE_NAME("engrave_tombstone");
- engrave_tombstone(std::move(g_output_fd), &unwinder, thread_info, g_target_thread, process_info,
- &open_files, &amfd_data);
+ engrave_tombstone(std::move(g_output_fd), std::move(g_proto_fd), &unwinder, thread_info,
+ g_target_thread, process_info, &open_files, &amfd_data);
}
}