Loading debuggerd/handler/debuggerd_handler.cpp +22 −11 Original line number Diff line number Diff line Loading @@ -67,11 +67,22 @@ static debuggerd_callbacks_t g_callbacks; 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. #define fatal(...) \ do { \ __libc_format_log(ANDROID_LOG_FATAL, "libc", __VA_ARGS__); \ _exit(1); \ } while (0) static void __noreturn __printflike(1, 2) fatal(const char* fmt, ...) { va_list args; va_start(args, fmt); __libc_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args); _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 Loading Loading @@ -192,7 +203,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) { int pipefds[2]; 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. Loading @@ -209,7 +220,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) { snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid); execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr); fatal("exec failed: %s", strerror(errno)); fatal_errno("exec failed"); } else { close(pipefds[1]); char buf[4]; Loading Loading @@ -264,7 +275,7 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) { if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) { int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info); if (rc != 0) { fatal("failed to resend signal during crash: %s", strerror(errno)); fatal_errno("failed to resend signal during crash"); } } Loading Loading @@ -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, &thread_info, nullptr, nullptr, &thread_info.pseudothread_tid); 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... Loading Loading @@ -366,12 +377,12 @@ void debuggerd_init(debuggerd_callbacks_t* callbacks) { void* thread_stack_allocation = mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 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; 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... Loading Loading
debuggerd/handler/debuggerd_handler.cpp +22 −11 Original line number Diff line number Diff line Loading @@ -67,11 +67,22 @@ static debuggerd_callbacks_t g_callbacks; 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. #define fatal(...) \ do { \ __libc_format_log(ANDROID_LOG_FATAL, "libc", __VA_ARGS__); \ _exit(1); \ } while (0) static void __noreturn __printflike(1, 2) fatal(const char* fmt, ...) { va_list args; va_start(args, fmt); __libc_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args); _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 Loading Loading @@ -192,7 +203,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) { int pipefds[2]; 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. Loading @@ -209,7 +220,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) { snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid); execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr); fatal("exec failed: %s", strerror(errno)); fatal_errno("exec failed"); } else { close(pipefds[1]); char buf[4]; Loading Loading @@ -264,7 +275,7 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) { if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) { int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info); if (rc != 0) { fatal("failed to resend signal during crash: %s", strerror(errno)); fatal_errno("failed to resend signal during crash"); } } Loading Loading @@ -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, &thread_info, nullptr, nullptr, &thread_info.pseudothread_tid); 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... Loading Loading @@ -366,12 +377,12 @@ void debuggerd_init(debuggerd_callbacks_t* callbacks) { void* thread_stack_allocation = mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 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; 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... Loading