Make abort messages available to debuggerd.
This adds __libc_fatal, cleans up the internal logging code a bit more,
and switches suitable callers over to __libc_fatal. In addition to logging,
__libc_fatal stashes the message somewhere that the debuggerd signal handler
can find it before calling abort.
In the debuggerd signal handler, we pass this address to debuggerd so that
it can come back with ptrace to read the message and present it to the user.
Bug: 8531731
(cherry picked from commit 0d787c1fa18c6a1f29ef9840e28a68cf077be1de)
Change-Id: I5daeeaa36c1fc23f7f437d73a19808d9d558dd4d
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index 6fddb1c..a7c0591 100644
--- a/linker/debugger.cpp
+++ b/linker/debugger.cpp
@@ -52,8 +52,12 @@
/* message sent over the socket */
struct debugger_msg_t {
- debugger_action_t action;
- pid_t tid;
+ // version 1 included:
+ debugger_action_t action;
+ pid_t tid;
+
+ // version 2 added:
+ uintptr_t abort_msg_address;
};
// see man(2) prctl, specifically the section about PR_GET_NAME
@@ -154,14 +158,14 @@
sigemptyset(&newact.sa_mask);
if (sigaction(signum, &newact, &oldact) < 0) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "Failed testing for SA_SIGINFO: %s",
+ __libc_format_log(ANDROID_LOG_WARN, "libc", "Failed testing for SA_SIGINFO: %s",
strerror(errno));
- return 0;
+ return false;
}
bool ret = (oldact.sa_flags & SA_SIGINFO) != 0;
if (sigaction(signum, &oldact, NULL) == -1) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "Restore failed in test for SA_SIGINFO: %s",
+ __libc_format_log(ANDROID_LOG_WARN, "libc", "Restore failed in test for SA_SIGINFO: %s",
strerror(errno));
}
return ret;
@@ -186,19 +190,17 @@
int s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM);
if (s >= 0) {
- /* debugger knows our pid from the credentials on the
- * local socket but we need to tell it our tid. It
- * is paranoid and will verify that we are giving a tid
- * that's actually in our process
- */
- int ret;
+ // debuggerd knows our pid from the credentials on the
+ // local socket but we need to tell it the tid of the crashing thread.
+ // debuggerd will be paranoid and verify that we sent a tid
+ // that's actually in our process.
debugger_msg_t msg;
msg.action = DEBUGGER_ACTION_CRASH;
msg.tid = tid;
- ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
+ msg.abort_msg_address = reinterpret_cast<uintptr_t>(gAbortMessage);
+ int ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
if (ret == sizeof(msg)) {
- /* if the write failed, there is no point to read on
- * the file descriptor. */
+ // if the write failed, there is no point trying to read a response.
ret = TEMP_FAILURE_RETRY(read(s, &tid, 1));
int saved_errno = errno;
notify_gdb_of_libraries();