Abort harder.
Some PoS internal system can't cope with more than 4 stack frames,
so the fact that our abort(3) implementation takes 4 frames by itself
makes it useless.
Re-reading POSIX, it only says "behaves as if", so the previous
implementation chain wasn't mandatory and we can just go straight to
calling tgkill...
Before:
#00 pc 0000000000069be4 /system/lib64/libc.so (tgkill+8)
#01 pc 0000000000066d50 /system/lib64/libc.so (pthread_kill+64)
#02 pc 0000000000028110 /system/lib64/libc.so (raise+24)
#03 pc 000000000001d4ec /system/lib64/libc.so (abort+52)
After:
#00 pc 0000000000069bc8 /system/lib64/libc.so (tgkill+8)
#01 pc 000000000001d4c8 /system/lib64/libc.so (abort+80)
#02 pc 0000000000001494 /system/xbin/crasher64 (_ZL9do_actionPKc+872)
#03 pc 00000000000010e0 /system/xbin/crasher64 (main+88)
This is less useful on 32-bit ARM because there there's an extra trampoline
from an assembler abort(3) implementation, so you'll still only get one
meaningful stack frame. But every other architecture will now get two!
But wait!
It turns out that the assembler hack isn't needed any more. Here we are
unwinding just fine all the way through the 32-bit ARM crasher:
Before (with direct call to tgkill but still using the assembler):
#00 pc 00049e7c /system/lib/libc.so (tgkill+12)
#01 pc 00019c6f /system/lib/libc.so (__libc_android_abort+50)
#02 pc 000181f8 /system/lib/libc.so (abort+4)
#03 pc 00001025 /system/xbin/crasher (_ZL9do_actionPKc+656)
#04 pc 00017721 /system/lib/libc.so (__libc_init+48)
#05 pc 00000b38 /system/xbin/crasher (_start+96)
After:
#00 pc 00049e6c /system/lib/libc.so (tgkill+12)
#01 pc 00019c5f /system/lib/libc.so (abort+50)
#02 pc 00001025 /system/xbin/crasher (_ZL9do_actionPKc+656)
#03 pc 00017721 /system/lib/libc.so (__libc_init+48)
#04 pc 00000b38 /system/xbin/crasher (_start+96)
(As you can see, the fact that we see __libc_init rather than main was true
with the assembler stub too, so that's not a regression even if it does seem
odd...)
Bug: N/A
Test: ran crasher64
Change-Id: I9dd5b214c495604c8b502c7ec0de3631080d8c29
diff --git a/libc/Android.bp b/libc/Android.bp
index 82d2b05..2176ba6 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -779,7 +779,6 @@
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "arch-arm/bionic/abort_arm.S",
"arch-arm/bionic/atomics_arm.c",
"arch-arm/bionic/__bionic_clone.S",
"arch-arm/bionic/_exit_with_stack_teardown.S",
diff --git a/libc/arch-arm/bionic/abort_arm.S b/libc/arch-arm/bionic/abort_arm.S
deleted file mode 100644
index 1039502..0000000
--- a/libc/arch-arm/bionic/abort_arm.S
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-/*
- * Coding the abort function in assembly so that registers are guaranteed to
- * be preserved properly regardless of GCC's assumption on the "noreturn"
- * attribute. When the registers are not properly preserved we won't be able
- * to unwind the stack all the way to the bottom to fully reveal the call
- * sequence when the crash happens.
- */
-ENTRY(abort)
- stmfd sp!, {r3, r14}
- .cfi_def_cfa_offset 8
- .cfi_rel_offset r3, 0
- .cfi_rel_offset r14, 4
- bl __libc_android_abort
-END(abort)
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index 75413c6..9aefd44 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -31,12 +31,9 @@
#include <stdlib.h>
#include <unistd.h>
-#ifdef __arm__
-extern "C" __LIBC_HIDDEN__ void __libc_android_abort()
-#else
-void abort()
-#endif
-{
+extern "C" int tgkill(int tgid, int tid, int sig);
+
+void abort() {
// Don't block SIGABRT to give any signal handler a chance; we ignore
// any errors -- X311J doesn't allow abort to return anyway.
sigset_t mask;
@@ -44,7 +41,7 @@
sigdelset(&mask, SIGABRT);
sigprocmask(SIG_SETMASK, &mask, NULL);
- raise(SIGABRT);
+ tgkill(getpid(), gettid(), SIGABRT);
// If SIGABRT ignored, or caught and the handler returns,
// remove the SIGABRT signal handler and raise SIGABRT again.
@@ -54,6 +51,9 @@
sigemptyset(&sa.sa_mask);
sigaction(SIGABRT, &sa, &sa);
sigprocmask(SIG_SETMASK, &mask, NULL);
- raise(SIGABRT);
- _exit(1);
+
+ tgkill(getpid(), gettid(), SIGABRT);
+
+ // If we get this far, just exit.
+ _exit(127);
}