1 --- abort.c.orig 2010-09-07 22:42:56.000000000 -0700
2 +++ abort.c 2010-09-07 22:46:29.000000000 -0700
3 @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/
11 @@ -43,11 +44,22 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/
13 #include "libc_private.h"
15 +#include "CrashReporterClient.h"
18 +extern void (*__cleanup)();
19 +extern void __abort(void) __dead2;
21 +#define TIMEOUT 10000 /* 10 milliseconds */
28 + if (!CRGetCrashLogMessage())
29 + CRSetCrashLogMessage("abort() called");
32 * POSIX requires we flush stdio buffers on abort.
33 * XXX ISO C requires that abort() be async-signal-safe.
34 @@ -61,19 +73,90 @@ abort()
35 * any errors -- ISO C doesn't allow abort to return anyway.
37 sigdelset(&act.sa_mask, SIGABRT);
38 - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
39 - (void)raise(SIGABRT);
41 + /* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread
42 + * This helps gdb focus on the thread calling abort()
44 + if (__is_threaded) {
45 + /* Block all signals on all other threads */
47 + sigfillset(&fullmask);
48 + (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
50 + /* <rdar://problem/8400096> Set the workqueue killable */
51 + __pthread_workqueue_setkill(1);
53 + (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
54 + (void)pthread_kill(pthread_self(), SIGABRT);
56 + (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
57 + (void)kill(getpid(), SIGABRT);
59 + usleep(TIMEOUT); /* give time for signal to happen */
62 * If SIGABRT was ignored, or caught and the handler returns, do
63 * it again, only harder.
68 +__private_extern__ void
71 + struct sigaction act;
73 + if (!CRGetCrashLogMessage())
74 + CRSetCrashLogMessage("__abort() called");
75 act.sa_handler = SIG_DFL;
77 sigfillset(&act.sa_mask);
78 (void)_sigaction(SIGABRT, &act, NULL);
79 sigdelset(&act.sa_mask, SIGABRT);
81 + /* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread
82 + * This helps gdb focus on the thread calling abort()
84 + if (__is_threaded) {
85 + /* Block all signals on all other threads */
87 + sigfillset(&fullmask);
88 + (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
90 + /* <rdar://problem/8400096> Set the workqueue killable */
91 + __pthread_workqueue_setkill(1);
93 + (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
94 + (void)pthread_kill(pthread_self(), SIGABRT);
96 + (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
97 + (void)kill(getpid(), SIGABRT);
99 + usleep(TIMEOUT); /* give time for signal to happen */
101 + /* If for some reason SIGABRT was not delivered, we exit using __builtin_trap
102 + * which generates an illegal instruction on i386: <rdar://problem/8400958>
103 + * and SIGTRAP on arm.
105 + sigfillset(&act.sa_mask);
106 + sigdelset(&act.sa_mask, SIGILL);
107 + sigdelset(&act.sa_mask, SIGTRAP);
108 (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
109 - (void)raise(SIGABRT);
114 +__private_extern__ void
115 +abort_report_np(const char *fmt, ...)
120 + if ((s = _simple_salloc()) != NULL) {
122 + _simple_vsprintf(s, fmt, ap);
124 + CRSetCrashLogMessage(_simple_string(s));
126 + CRSetCrashLogMessage(fmt); /* the format string is better than nothing */