Clean up debugger.cpp slightly.

In particular, don't do weird things with 'int tid'.

Change-Id: I0fd9158a452967163508ada8987de9494ad5f9af
This commit is contained in:
Elliott Hughes 2014-01-31 17:27:00 -08:00
parent 4939d6d842
commit 62e9c76ee8

View File

@ -96,10 +96,10 @@ static int socket_abstract_client(const char* name, int type) {
return -1; return -1;
} }
int err = TEMP_FAILURE_RETRY(connect(s, reinterpret_cast<sockaddr*>(&addr), alen)); int rc = TEMP_FAILURE_RETRY(connect(s, reinterpret_cast<sockaddr*>(&addr), alen));
if (err == -1) { if (rc == -1) {
close(s); close(s);
s = -1; return -1;
} }
return s; return s;
@ -180,69 +180,64 @@ static bool have_siginfo(int signum) {
* Catches fatal signals so we can ask debuggerd to ptrace us before * Catches fatal signals so we can ask debuggerd to ptrace us before
* we crash. * we crash.
*/ */
void debuggerd_signal_handler(int n, siginfo_t* info, void*) { void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*) {
/* // It's possible somebody cleared the SA_SIGINFO flag, which would mean
* It's possible somebody cleared the SA_SIGINFO flag, which would mean // our "info" arg holds an undefined value.
* our "info" arg holds an undefined value. if (!have_siginfo(signal_number)) {
*/
if (!have_siginfo(n)) {
info = NULL; info = NULL;
} }
log_signal_summary(n, info); log_signal_summary(signal_number, info);
pid_t tid = gettid();
int s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM); int s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM);
if (s != -1) {
if (s >= 0) {
// debuggerd knows our pid from the credentials on the // debuggerd knows our pid from the credentials on the
// local socket but we need to tell it the tid of the crashing thread. // 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 // debuggerd will be paranoid and verify that we sent a tid
// that's actually in our process. // that's actually in our process.
debugger_msg_t msg; debugger_msg_t msg;
msg.action = DEBUGGER_ACTION_CRASH; msg.action = DEBUGGER_ACTION_CRASH;
msg.tid = tid; msg.tid = gettid();
msg.abort_msg_address = reinterpret_cast<uintptr_t>(gAbortMessage); msg.abort_msg_address = reinterpret_cast<uintptr_t>(gAbortMessage);
int ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))); int ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
if (ret == sizeof(msg)) { if (ret == sizeof(msg)) {
// if the write failed, there is no point trying to read a response. // If the write failed, there is no point trying to read a response.
ret = TEMP_FAILURE_RETRY(read(s, &tid, 1)); char debuggerd_ack;
ret = TEMP_FAILURE_RETRY(read(s, &debuggerd_ack, 1));
int saved_errno = errno; int saved_errno = errno;
notify_gdb_of_libraries(); notify_gdb_of_libraries();
errno = saved_errno; errno = saved_errno;
} }
if (ret < 0) { if (ret < 0) {
/* read or write failed -- broken connection? */ // read or write failed -- broken connection?
__libc_format_log(ANDROID_LOG_FATAL, "libc", "Failed while talking to debuggerd: %s", __libc_format_log(ANDROID_LOG_FATAL, "libc", "Failed while talking to debuggerd: %s",
strerror(errno)); strerror(errno));
} }
close(s); close(s);
} else { } else {
/* socket failed; maybe process ran out of fds */ // socket failed; maybe process ran out of fds?
__libc_format_log(ANDROID_LOG_FATAL, "libc", "Unable to open connection to debuggerd: %s", __libc_format_log(ANDROID_LOG_FATAL, "libc", "Unable to open connection to debuggerd: %s",
strerror(errno)); strerror(errno));
} }
/* remove our net so we fault for real when we return */ // Remove our net so we fault for real when we return.
signal(n, SIG_DFL); signal(signal_number, SIG_DFL);
/* // These signals are not re-thrown when we resume. This means that
* These signals are not re-thrown when we resume. This means that // crashing due to (say) SIGPIPE doesn't work the way you'd expect it
* crashing due to (say) SIGPIPE doesn't work the way you'd expect it // to. We work around this by throwing them manually. We don't want
* to. We work around this by throwing them manually. We don't want // to do this for *all* signals because it'll screw up the address for
* to do this for *all* signals because it'll screw up the address for // faults like SIGSEGV.
* faults like SIGSEGV. switch (signal_number) {
*/
switch (n) {
case SIGABRT: case SIGABRT:
case SIGFPE: case SIGFPE:
case SIGPIPE: case SIGPIPE:
#if defined(SIGSTKFLT) #if defined(SIGSTKFLT)
case SIGSTKFLT: case SIGSTKFLT:
#endif #endif
(void) tgkill(getpid(), gettid(), n); tgkill(getpid(), gettid(), signal_number);
break; break;
default: // SIGILL, SIGBUS, SIGSEGV default: // SIGILL, SIGBUS, SIGSEGV
break; break;