diff options
author | Andy McFadden <fadden@android.com> | 2012-03-08 11:14:37 -0800 |
---|---|---|
committer | Andy McFadden <fadden@android.com> | 2012-03-08 11:14:37 -0800 |
commit | ca9a0712b89eee017c2a40056c101d86c1f7d02f (patch) | |
tree | e9fde715b179915d7c8928f8b989c5079b7c7b45 /linker | |
parent | 654325de026a2ca5b76b8b40e576c959d8211fdc (diff) | |
download | bionic-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.c | 20 |
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() |