1 // BUILD(macos): $CXX main.cpp -o $BUILD_DIR/NSAddImage-fail.exe -Wno-deprecated-declarations -DRUN_DIR="$RUN_DIR"
3 // BUILD(ios,tvos,watchos,bridgeos):
5 // NO_CRASH_LOG: NSAddImage-fail.exe
7 // RUN: ./NSAddImage-fail.exe return
8 // RUN: ./NSAddImage-fail.exe abort
16 #include <mach-o/dyld.h>
17 #include <mach-o/dyld_priv.h>
18 #include <System/sys/reason.h>
19 #include <System/sys/proc_info.h>
20 #include <System/kern/kern_cdata.h>
22 #include "test_support.h"
26 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
27 const char* arg
= argv
[1];
29 if ( strcmp(arg
, "return") == 0 ) {
30 const struct mach_header
* mh
= NSAddImage("/xqz/42/libnotfound.xxx", NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
);
34 FAIL("Got mh non-existent image");
35 } else if (strcmp(arg
, "abort-child") == 0) {
36 // run with nocr which print BEGIN/PASS/FAIL
37 NSAddImage("/xqz/42/libnotfound.xxx", 0);
38 } else if (strcmp(arg
, "abort") == 0) {
40 process
.set_executable_path(RUN_DIR
"/NSAddImage-fail.exe");
41 const char* args
[] = {"abort-child", NULL
};
42 process
.set_args(args
);
43 const char* env
[] = { "TEST_OUTPUT=None", NULL
};
45 process
.set_crash_handler(^(task_t task
) {
46 LOG("Crash for task=%u", task
);
47 mach_vm_address_t corpse_data
;
48 mach_vm_size_t corpse_size
;
49 if (task_map_corpse_info_64(mach_task_self(), task
, &corpse_data
, &corpse_size
) != KERN_SUCCESS
) {
50 FAIL("Could not read corpse data");
52 kcdata_iter_t autopsyData
= kcdata_iter((void*)corpse_data
, corpse_size
);
53 if (!kcdata_iter_valid(autopsyData
)) {
54 FAIL("Corpse Data Invalid");
56 kcdata_iter_t exitReasonData
= kcdata_iter_find_type(autopsyData
, EXIT_REASON_SNAPSHOT
);
57 if (!kcdata_iter_valid(exitReasonData
)) {
58 FAIL("Could not find exit data");
60 struct exit_reason_snapshot
*ers
= (struct exit_reason_snapshot
*)kcdata_iter_payload(exitReasonData
);
62 if ( ers
->ers_namespace
!= OS_REASON_DYLD
) {
63 FAIL("eri_namespace (%d) != OS_REASON_DYLD", ers
->ers_namespace
);
65 if ( ers
->ers_code
!= DYLD_EXIT_REASON_OTHER
) {
66 FAIL("eri_code (%lld) != DYLD_EXIT_REASON_OTHER", ers
->ers_code
);
68 kcdata_iter_t iter
= kcdata_iter((void*)corpse_data
, corpse_size
);
70 KCDATA_ITER_FOREACH(iter
) {
71 if (kcdata_iter_type(iter
) == KCDATA_TYPE_NESTED_KCDATA
) {
72 kcdata_iter_t nestedIter
= kcdata_iter(kcdata_iter_payload(iter
), kcdata_iter_size(iter
));
73 if ( kcdata_iter_type(nestedIter
) != KCDATA_BUFFER_BEGIN_OS_REASON
){
76 kcdata_iter_t payloadIter
= kcdata_iter_find_type(nestedIter
, EXIT_REASON_USER_PAYLOAD
);
77 if ( !kcdata_iter_valid(payloadIter
) ) {
78 FAIL("invalid kcdata payload iterator from payload data");
80 const dyld_abort_payload
* dyldInfo
= (dyld_abort_payload
*)kcdata_iter_payload(payloadIter
);
82 if ( dyldInfo
->version
!= 1 ) {
83 FAIL("dyld payload is not version 1");
88 FAIL("Did not find EXIT_REASON_USER_PAYLOAD");