summaryrefslogtreecommitdiffstats
path: root/linker
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2012-03-08 11:14:37 -0800
committerAndy McFadden <fadden@android.com>2012-03-08 11:14:37 -0800
commitca9a0712b89eee017c2a40056c101d86c1f7d02f (patch)
treee9fde715b179915d7c8928f8b989c5079b7c7b45 /linker
parent654325de026a2ca5b76b8b40e576c959d8211fdc (diff)
downloadbionic-ca9a0712b89eee017c2a40056c101d86c1f7d02f.zip
bionic-ca9a0712b89eee017c2a40056c101d86c1f7d02f.tar.gz
bionic-ca9a0712b89eee017c2a40056c101d86c1f7d02f.tar.bz2
Re-throw signals
If we catch a fatal signal that won't automatically re-throw when the thread resumes, re-throw it manually. (Common examples are SIGPIPE and the SIGFPE from integer division by zero.) Change-Id: I329e6d4db907047c555957b42cbd09c50fc808e7
Diffstat (limited to 'linker')
-rw-r--r--linker/debugger.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/linker/debugger.c b/linker/debugger.c
index 40411b1..899a5b2 100644
--- a/linker/debugger.c
+++ b/linker/debugger.c
@@ -40,6 +40,8 @@
#include <sys/socket.h>
#include <sys/un.h>
+extern int tgkill(int tgid, int tid, int sig);
+
void notify_gdb_of_libraries();
#define RETRY_ON_EINTR(ret,cond) \
@@ -181,6 +183,24 @@ void debugger_signal_handler(int n, siginfo_t* info, void* unused)
/* remove our net so we fault for real when we return */
signal(n, SIG_DFL);
+
+ /*
+ * 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
+ * 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
+ * faults like SIGSEGV.
+ */
+ switch (n) {
+ case SIGABRT:
+ case SIGFPE:
+ case SIGPIPE:
+ case SIGSTKFLT:
+ (void) tgkill(getpid(), gettid(), n);
+ break;
+ default: // SIGILL, SIGBUS, SIGSEGV
+ break;
+ }
}
void debugger_init()