am ed29345c
: Merge "Clean up debugger.cpp slightly."
* commit 'ed29345c22acec61e4ef8953baefc64dc750c812': Clean up debugger.cpp slightly.
This commit is contained in:
commit
91b5f5a0cf
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user