Merge "debuggerd_handler: add and use fatal_errno." am: bcabf10397 am: 9a4933e1a6
am: 90117d6632
Change-Id: I80376c6ce26acd60e3e92ef51bf3e2854017b1d5
This commit is contained in:
commit
5d8419c84a
1 changed files with 22 additions and 11 deletions
|
|
@ -67,11 +67,22 @@ static debuggerd_callbacks_t g_callbacks;
|
||||||
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
// Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler.
|
// Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler.
|
||||||
#define fatal(...) \
|
static void __noreturn __printflike(1, 2) fatal(const char* fmt, ...) {
|
||||||
do { \
|
va_list args;
|
||||||
__libc_format_log(ANDROID_LOG_FATAL, "libc", __VA_ARGS__); \
|
va_start(args, fmt);
|
||||||
_exit(1); \
|
__libc_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args);
|
||||||
} while (0)
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __noreturn __printflike(1, 2) fatal_errno(const char* fmt, ...) {
|
||||||
|
int err = errno;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
char buf[4096];
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||||
|
fatal("%s: %s", buf, strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes a summary of the signal to the log file. We do this so that, if
|
* Writes a summary of the signal to the log file. We do this so that, if
|
||||||
|
|
@ -192,7 +203,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) {
|
||||||
|
|
||||||
int pipefds[2];
|
int pipefds[2];
|
||||||
if (pipe(pipefds) != 0) {
|
if (pipe(pipefds) != 0) {
|
||||||
fatal("failed to create pipe");
|
fatal_errno("failed to create pipe");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't use fork(2) to avoid calling pthread_atfork handlers.
|
// Don't use fork(2) to avoid calling pthread_atfork handlers.
|
||||||
|
|
@ -209,7 +220,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) {
|
||||||
snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid);
|
snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid);
|
||||||
execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr);
|
execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr);
|
||||||
|
|
||||||
fatal("exec failed: %s", strerror(errno));
|
fatal_errno("exec failed");
|
||||||
} else {
|
} else {
|
||||||
close(pipefds[1]);
|
close(pipefds[1]);
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
|
@ -264,7 +275,7 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) {
|
||||||
if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) {
|
if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) {
|
||||||
int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info);
|
int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
fatal("failed to resend signal during crash: %s", strerror(errno));
|
fatal_errno("failed to resend signal during crash");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -336,7 +347,7 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*)
|
||||||
CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID,
|
CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID,
|
||||||
&thread_info, nullptr, nullptr, &thread_info.pseudothread_tid);
|
&thread_info, nullptr, nullptr, &thread_info.pseudothread_tid);
|
||||||
if (child_pid == -1) {
|
if (child_pid == -1) {
|
||||||
fatal("failed to spawn debuggerd dispatch thread: %s", strerror(errno));
|
fatal_errno("failed to spawn debuggerd dispatch thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the child to start...
|
// Wait for the child to start...
|
||||||
|
|
@ -366,12 +377,12 @@ void debuggerd_init(debuggerd_callbacks_t* callbacks) {
|
||||||
void* thread_stack_allocation =
|
void* thread_stack_allocation =
|
||||||
mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
if (thread_stack_allocation == MAP_FAILED) {
|
if (thread_stack_allocation == MAP_FAILED) {
|
||||||
fatal("failed to allocate debuggerd thread stack");
|
fatal_errno("failed to allocate debuggerd thread stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
char* stack = static_cast<char*>(thread_stack_allocation) + PAGE_SIZE;
|
char* stack = static_cast<char*>(thread_stack_allocation) + PAGE_SIZE;
|
||||||
if (mprotect(stack, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
|
if (mprotect(stack, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
|
||||||
fatal("failed to mprotect debuggerd thread stack");
|
fatal_errno("failed to mprotect debuggerd thread stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stack grows negatively, set it to the last byte in the page...
|
// Stack grows negatively, set it to the last byte in the page...
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue