1 #include <dispatch/dispatch.h>
4 #include <sys/sysctl.h>
5 #include <mach-o/loader.h>
14 /* TODO: Re-enable after deciding how best to interact with this symbol. */
16 * NOTE: 8006611: converted to using libCrashReporterClient.a, so shouldn't
17 * use __crashreporter_info__.
20 static char __crashreporter_info_buff__
[2048];
21 const char *__crashreporter_info__
= &__crashreporter_info_buff__
[0];
22 asm (".desc __crashreporter_info__, 0x10");
25 #define osx_atomic_cmpxchg(p, o, n) __sync_bool_compare_and_swap((p), (o), (n))
28 _osx_basename(const char *p
)
30 return ((strrchr(p
, '/') ? : p
- 1) + 1);
36 static char s_build
[16];
37 static long s_once
= 0;
38 if (osx_atomic_cmpxchg(&s_once
, 0, 1)) {
39 int mib
[] = { CTL_KERN
, KERN_OSVERSION
};
40 size_t sz
= sizeof(s_build
);
42 (void)sysctl(mib
, 2, s_build
, &sz
, NULL
, 0);
49 _osx_get_image_uuid(void *hdr
, uuid_t uuid
)
52 struct mach_header_64
*_hdr
= (struct mach_header_64
*)hdr
;
54 struct mach_header
*_hdr
= (struct mach_header
*)hdr
;
58 size_t next
= sizeof(*_hdr
);
59 struct load_command
*cur
= NULL
;
60 for (i
= 0; i
< _hdr
->ncmds
; i
++) {
61 cur
= (struct load_command
*)((uintptr_t)_hdr
+ next
);
62 if (cur
->cmd
== LC_UUID
) {
63 struct uuid_command
*cmd
= (struct uuid_command
*)cur
;
64 uuid_copy(uuid
, cmd
->uuid
);
70 if (i
== _hdr
->ncmds
) {
76 _osx_assumes_log(uint64_t code
)
80 const char *image_name
= NULL
;
82 uuid_string_t uuid_str
;
85 /* Get our caller's address so we can look it up with dladdr(3) and
86 * get info about the image.
88 if (backtrace(arr
, 2) == 2) {
89 /* dladdr(3) returns non-zero on success... for some reason. */
90 if (dladdr(arr
[1], &info
)) {
92 _osx_get_image_uuid(info
.dli_fbase
, uuid
);
94 uuid_unparse(uuid
, uuid_str
);
95 image_name
= _osx_basename(info
.dli_fname
);
97 offset
= arr
[1] - info
.dli_fbase
;
101 uuid_string_t uuid_str
;
103 uuid_clear(null_uuid
);
104 uuid_unparse(null_uuid
, uuid_str
);
106 image_name
= "unknown";
110 (void)snprintf(name
, sizeof(name
), "com.apple.assumes.%s", image_name
);
113 (void)snprintf(sig
, sizeof(sig
), "%s:%lu", uuid_str
, offset
);
116 (void)snprintf(result
, sizeof(result
), "0x%llx", code
);
118 char *prefix
= "Bug";
120 (void)snprintf(message
, sizeof(message
), "%s: %s: %s + %lu [%s]: %s", prefix
, _osx_get_build(), image_name
, offset
, uuid_str
, result
);
122 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
124 /* MessageTracer messages aren't logged to the regular syslog store, so
125 * we pre-log the message without any MessageTracer attributes so that
126 * we can see it in our regular syslog.
128 (void)asl_log(NULL
, msg
, ASL_LEVEL_ERR
, "%s", message
);
130 (void)asl_set(msg
, "com.apple.message.domain", name
);
131 (void)asl_set(msg
, "com.apple.message.signature", sig
);
132 (void)asl_set(msg
, "com.apple.message.value", result
);
134 (void)asl_log(NULL
, msg
, ASL_LEVEL_ERR
, "%s", message
);
139 /* For osx_assert(). We need to think more about how best to set the __crashreporter_info__ string.
140 * For example, calling into two functions will basically smash the register state at the time of
141 * the assertion failure, causing potentially valuable information to be lost. Also, just setting
142 * the __crashreporter_info__ to a static string only involves one instruction, whereas a function
143 * call involves... well, more.
147 osx_hardware_trap(const char *fmt
, ...)
152 osx_hardware_trapv(fmt
, ap
);
158 osx_hardware_trapv(const char *fmt
, va_list ap
)
160 (void)vsnprintf(__crashreporter_info_buff__
, sizeof(__crashreporter_info_buff__
), fmt
, ap
);