2 * Copyright (c) 2016 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 #include <sys/reason.h>
24 #include <sys/types.h>
27 #include <os/reason_private.h>
30 /* Crash simulation */
32 extern int pthread_current_stack_contains_np(const void *, unsigned long);
34 __darwin_check_fd_set_overflow(int n
, const void *fd_set
, int unlimited_select
)
37 os_fault_with_payload(OS_REASON_LIBSYSTEM
, OS_REASON_LIBSYSTEM_CODE_FAULT
,
38 &n
, sizeof(n
), "FD_SET underflow", 0);
42 if (n
>= __DARWIN_FD_SETSIZE
) {
43 if (pthread_current_stack_contains_np((const void *) fd_set
, sizeof(struct fd_set
))) {
44 if (!unlimited_select
) {
45 os_fault_with_payload(OS_REASON_LIBSYSTEM
, OS_REASON_LIBSYSTEM_CODE_FAULT
,
46 &n
, sizeof(n
), "FD_SET overflow", 0);
59 /* System call entry points */
60 int __terminate_with_payload(int pid
, uint32_t reason_namespace
, uint64_t reason_code
,
61 void *payload
, uint32_t payload_size
, const char *reason_string
,
62 uint64_t reason_flags
);
64 void __abort_with_payload(uint32_t reason_namespace
, uint64_t reason_code
,
65 void *payload
, uint32_t payload_size
, const char *reason_string
,
66 uint64_t reason_flags
);
68 static void abort_with_payload_wrapper_internal(uint32_t reason_namespace
, uint64_t reason_code
,
69 void *payload
, uint32_t payload_size
, const char *reason_string
,
70 uint64_t reason_flags
) __attribute__((noreturn
, cold
));
72 /* System call wrappers */
74 terminate_with_reason(int pid
, uint32_t reason_namespace
, uint64_t reason_code
,
75 const char *reason_string
, uint64_t reason_flags
)
77 return __terminate_with_payload(pid
, reason_namespace
, reason_code
, 0, 0,
78 reason_string
, reason_flags
);
82 terminate_with_payload(int pid
, uint32_t reason_namespace
, uint64_t reason_code
,
83 void *payload
, uint32_t payload_size
,
84 const char *reason_string
, uint64_t reason_flags
)
86 return __terminate_with_payload(pid
, reason_namespace
, reason_code
, payload
,
87 payload_size
, reason_string
, reason_flags
);
91 abort_with_payload_wrapper_internal(uint32_t reason_namespace
, uint64_t reason_code
,
92 void *payload
, uint32_t payload_size
, const char *reason_string
,
93 uint64_t reason_flags
)
95 sigset_t unmask_signal
;
97 /* Try to unmask SIGABRT before trapping to the kernel */
98 sigemptyset(&unmask_signal
);
99 sigaddset(&unmask_signal
, SIGABRT
);
100 sigprocmask(SIG_UNBLOCK
, &unmask_signal
, NULL
);
102 __abort_with_payload(reason_namespace
, reason_code
, payload
, payload_size
,
103 reason_string
, reason_flags
);
105 /* If sending a SIGABRT failed, we fall back to SIGKILL */
106 terminate_with_payload(getpid(), reason_namespace
, reason_code
, payload
, payload_size
,
107 reason_string
, reason_flags
| OS_REASON_FLAG_ABORT
);
109 __builtin_unreachable();
113 abort_with_reason(uint32_t reason_namespace
, uint64_t reason_code
, const char *reason_string
,
114 uint64_t reason_flags
)
116 abort_with_payload_wrapper_internal(reason_namespace
, reason_code
, 0, 0, reason_string
, reason_flags
);
120 abort_with_payload(uint32_t reason_namespace
, uint64_t reason_code
, void *payload
,
121 uint32_t payload_size
, const char *reason_string
,
122 uint64_t reason_flags
)
124 abort_with_payload_wrapper_internal(reason_namespace
, reason_code
, payload
, payload_size
,
125 reason_string
, reason_flags
);