diff options
author | Josh Gao | 2017-01-31 15:13:46 -0600 |
---|---|---|
committer | Josh Gao | 2017-01-31 16:59:05 -0600 |
commit | 6462bb41e021090d44d41d6f03d0e071e1e19ea6 (patch) | |
tree | 20a5df2c18048e35c8d274ea0649f799aa244492 /debuggerd/handler | |
parent | 301e7e2cdbafbb75796dff72a0a03028f739e278 (diff) | |
download | platform-system-core-6462bb41e021090d44d41d6f03d0e071e1e19ea6.tar.gz platform-system-core-6462bb41e021090d44d41d6f03d0e071e1e19ea6.tar.xz platform-system-core-6462bb41e021090d44d41d6f03d0e071e1e19ea6.zip |
debuggerd_handler: add and use fatal_errno.
Bug: none
Test: mma
Change-Id: I24d913abdbe74f9463feda78f7817ca8b92af9cc
Diffstat (limited to 'debuggerd/handler')
-rw-r--r-- | debuggerd/handler/debuggerd_handler.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp index cd491d627..9469bbdeb 100644 --- a/debuggerd/handler/debuggerd_handler.cpp +++ b/debuggerd/handler/debuggerd_handler.cpp | |||
@@ -67,11 +67,22 @@ static debuggerd_callbacks_t g_callbacks; | |||
67 | static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER; | 67 | static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER; |
68 | 68 | ||
69 | // Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler. | 69 | // Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler. |
70 | #define fatal(...) \ | 70 | static void __noreturn __printflike(1, 2) fatal(const char* fmt, ...) { |
71 | do { \ | 71 | va_list args; |
72 | __libc_format_log(ANDROID_LOG_FATAL, "libc", __VA_ARGS__); \ | 72 | va_start(args, fmt); |
73 | _exit(1); \ | 73 | __libc_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args); |
74 | } while (0) | 74 | _exit(1); |
75 | } | ||
76 | |||
77 | static void __noreturn __printflike(1, 2) fatal_errno(const char* fmt, ...) { | ||
78 | int err = errno; | ||
79 | va_list args; | ||
80 | va_start(args, fmt); | ||
81 | |||
82 | char buf[4096]; | ||
83 | vsnprintf(buf, sizeof(buf), fmt, args); | ||
84 | fatal("%s: %s", buf, strerror(err)); | ||
85 | } | ||
75 | 86 | ||
76 | /* | 87 | /* |
77 | * Writes a summary of the signal to the log file. We do this so that, if | 88 | * 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) { | |||
192 | 203 | ||
193 | int pipefds[2]; | 204 | int pipefds[2]; |
194 | if (pipe(pipefds) != 0) { | 205 | if (pipe(pipefds) != 0) { |
195 | fatal("failed to create pipe"); | 206 | fatal_errno("failed to create pipe"); |
196 | } | 207 | } |
197 | 208 | ||
198 | // Don't use fork(2) to avoid calling pthread_atfork handlers. | 209 | // Don't use fork(2) to avoid calling pthread_atfork handlers. |
@@ -209,7 +220,7 @@ static int debuggerd_dispatch_pseudothread(void* arg) { | |||
209 | snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid); | 220 | snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid); |
210 | execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr); | 221 | execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr); |
211 | 222 | ||
212 | fatal("exec failed: %s", strerror(errno)); | 223 | fatal_errno("exec failed"); |
213 | } else { | 224 | } else { |
214 | close(pipefds[1]); | 225 | close(pipefds[1]); |
215 | char buf[4]; | 226 | char buf[4]; |
@@ -264,7 +275,7 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) { | |||
264 | if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) { | 275 | if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) { |
265 | int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info); | 276 | int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info); |
266 | if (rc != 0) { | 277 | if (rc != 0) { |
267 | fatal("failed to resend signal during crash: %s", strerror(errno)); | 278 | fatal_errno("failed to resend signal during crash"); |
268 | } | 279 | } |
269 | } | 280 | } |
270 | 281 | ||
@@ -336,7 +347,7 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*) | |||
336 | CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID, | 347 | CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID, |
337 | &thread_info, nullptr, nullptr, &thread_info.pseudothread_tid); | 348 | &thread_info, nullptr, nullptr, &thread_info.pseudothread_tid); |
338 | if (child_pid == -1) { | 349 | if (child_pid == -1) { |
339 | fatal("failed to spawn debuggerd dispatch thread: %s", strerror(errno)); | 350 | fatal_errno("failed to spawn debuggerd dispatch thread"); |
340 | } | 351 | } |
341 | 352 | ||
342 | // Wait for the child to start... | 353 | // Wait for the child to start... |
@@ -366,12 +377,12 @@ void debuggerd_init(debuggerd_callbacks_t* callbacks) { | |||
366 | void* thread_stack_allocation = | 377 | void* thread_stack_allocation = |
367 | mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | 378 | mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
368 | if (thread_stack_allocation == MAP_FAILED) { | 379 | if (thread_stack_allocation == MAP_FAILED) { |
369 | fatal("failed to allocate debuggerd thread stack"); | 380 | fatal_errno("failed to allocate debuggerd thread stack"); |
370 | } | 381 | } |
371 | 382 | ||
372 | char* stack = static_cast<char*>(thread_stack_allocation) + PAGE_SIZE; | 383 | char* stack = static_cast<char*>(thread_stack_allocation) + PAGE_SIZE; |
373 | if (mprotect(stack, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) { | 384 | if (mprotect(stack, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) { |
374 | fatal("failed to mprotect debuggerd thread stack"); | 385 | fatal_errno("failed to mprotect debuggerd thread stack"); |
375 | } | 386 | } |
376 | 387 | ||
377 | // Stack grows negatively, set it to the last byte in the page... | 388 | // Stack grows negatively, set it to the last byte in the page... |