]> git.saurik.com Git - apple/libc.git/blobdiff - stdlib/FreeBSD/abort.c
Libc-1439.40.11.tar.gz
[apple/libc.git] / stdlib / FreeBSD / abort.c
index 0fcbb9e5f794a7673aa93d80a8dac55f5f2df0ad..bac55ad101c90bd200a6a6a0694578dc87ab0be7 100644 (file)
@@ -27,6 +27,9 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wstrict-prototypes"
+
 #if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)abort.c    8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)abort.c    8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
@@ -40,15 +43,21 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.11 2007/01/09 00:28:09 imp E
 #include <stddef.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <stddef.h>
 #include <unistd.h>
 #include <pthread.h>
+#include <pthread_workqueue.h>
 #include "un-namespace.h"
 
 #include "libc_private.h"
 
 #include "un-namespace.h"
 
 #include "libc_private.h"
 
-#include "CrashReporterClient.h"
+#if __has_include(<CrashReporterClient.h>)
+#include <CrashReporterClient.h>
+#else
+#define CRGetCrashLogMessage() NULL
+#define CRSetCrashLogMessage(...)
+#endif
 #include "_simple.h"
 
 extern void (*__cleanup)();
 #include "_simple.h"
 
 extern void (*__cleanup)();
-extern void __abort(void) __dead2;
+extern void __abort(void) __cold __dead2;
 
 #define TIMEOUT        10000   /* 10 milliseconds */
 
 
 #define TIMEOUT        10000   /* 10 milliseconds */
 
@@ -74,24 +83,32 @@ abort()
         */
        sigdelset(&act.sa_mask, SIGABRT);
 
         */
        sigdelset(&act.sa_mask, SIGABRT);
 
+       /*
+        * Don't block SIGSEGV since we might trigger a segfault if the pthread
+        * struct is corrupt. The end user behavior is that the program will
+        * terminate with a SIGSEGV instead of a SIGABRT which is acceptable. If
+        * the user registers a SIGSEGV handler, then they are responsible for
+        * dealing with any corruption themselves and abort may not work.
+        * rdar://48853131
+        */
+       sigdelset(&act.sa_mask, SIGSEGV);
+       sigdelset(&act.sa_mask, SIGBUS);
+
        /* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread 
         * This helps gdb focus on the thread calling abort()
         */
        /* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread 
         * This helps gdb focus on the thread calling abort()
         */
-       if (__is_threaded) {
-           /* Block all signals on all other threads */
-           sigset_t fullmask;
-           sigfillset(&fullmask);
-           (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
-
-           /* <rdar://problem/8400096> Set the workqueue killable */
-           __pthread_workqueue_setkill(1);
-
-           (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
-           (void)pthread_kill(pthread_self(), SIGABRT);
-       } else {
-           (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
-           (void)kill(getpid(), SIGABRT);
-       }
+
+       /* Block all signals on all other threads */
+       sigset_t fullmask;
+       sigfillset(&fullmask);
+       (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
+
+       /* <rdar://problem/8400096> Set the workqueue killable */
+       __pthread_workqueue_setkill(1);
+
+       (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
+       (void)pthread_kill(pthread_self(), SIGABRT);
+
        usleep(TIMEOUT); /* give time for signal to happen */
 
        /*
        usleep(TIMEOUT); /* give time for signal to happen */
 
        /*
@@ -117,21 +134,18 @@ __abort()
        /* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread 
         * This helps gdb focus on the thread calling abort()
         */
        /* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread 
         * This helps gdb focus on the thread calling abort()
         */
-       if (__is_threaded) {
-           /* Block all signals on all other threads */
-           sigset_t fullmask;
-           sigfillset(&fullmask);
-           (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
-
-           /* <rdar://problem/8400096> Set the workqueue killable */
-           __pthread_workqueue_setkill(1);
-
-           (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
-           (void)pthread_kill(pthread_self(), SIGABRT);
-       } else {
-           (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
-           (void)kill(getpid(), SIGABRT);
-       }
+
+       /* Block all signals on all other threads */
+       sigset_t fullmask;
+       sigfillset(&fullmask);
+       (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
+
+       /* <rdar://problem/8400096> Set the workqueue killable */
+       __pthread_workqueue_setkill(1);
+
+       (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
+       (void)pthread_kill(pthread_self(), SIGABRT);
+
        usleep(TIMEOUT); /* give time for signal to happen */
 
        /* If for some reason SIGABRT was not delivered, we exit using __builtin_trap
        usleep(TIMEOUT); /* give time for signal to happen */
 
        /* If for some reason SIGABRT was not delivered, we exit using __builtin_trap
@@ -145,7 +159,7 @@ __abort()
        __builtin_trap();
 }
 
        __builtin_trap();
 }
 
-__private_extern__ void
+void
 abort_report_np(const char *fmt, ...)
 {
        _SIMPLE_STRING s;
 abort_report_np(const char *fmt, ...)
 {
        _SIMPLE_STRING s;
@@ -160,3 +174,4 @@ abort_report_np(const char *fmt, ...)
                CRSetCrashLogMessage(fmt); /* the format string is better than nothing */
        abort();
 }
                CRSetCrashLogMessage(fmt); /* the format string is better than nothing */
        abort();
 }
+#pragma clang diagnostic pop