3 // BUILD: $CXX main.cpp -o $BUILD_DIR/NSAddImage-fail.exe -Wno-deprecated-declarations -DRUN_DIR="$RUN_DIR"
5 // RUN: ./NSAddImage-fail.exe return
6 // RUN: ./NSAddImage-fail.exe abort
14 #include <mach-o/dyld.h>
15 #include <mach-o/dyld_priv.h>
16 #include <System/sys/reason.h>
17 #include <System/sys/proc_info.h>
18 #include <System/kern/kern_cdata.h>
20 #include "test_support.h"
24 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
25 const char* arg
= argv
[1];
27 if ( strcmp(arg
, "return") == 0 ) {
28 const struct mach_header
* mh
= NSAddImage("/xqz/42/libnotfound.xxx", NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
);
32 FAIL("Got mh non-existent image");
33 } else if (strcmp(arg
, "abort-child") == 0) {
34 // run with nocr which print BEGIN/PASS/FAIL
35 NSAddImage("/xqz/42/libnotfound.xxx", 0);
36 } else if (strcmp(arg
, "abort") == 0) {
38 process
.set_executable_path(RUN_DIR
"/NSAddImage-fail.exe");
39 const char* args
[] = {"abort-child", NULL
};
40 process
.set_args(args
);
41 const char* env
[] = { "TEST_OUTPUT=None", NULL
};
43 process
.set_crash_handler(^(task_t task
) {
44 LOG("Crash for task=%u", task
);
45 vm_address_t corpse_data
;
47 if (task_map_corpse_info(mach_task_self(), task
, &corpse_data
, &corpse_size
) != KERN_SUCCESS
) {
48 FAIL("Could not read corpse data");
50 kcdata_iter_t autopsyData
= kcdata_iter((void*)corpse_data
, corpse_size
);
51 if (!kcdata_iter_valid(autopsyData
)) {
52 FAIL("Corpse Data Invalid");
54 kcdata_iter_t exitReasonData
= kcdata_iter_find_type(autopsyData
, EXIT_REASON_SNAPSHOT
);
55 if (!kcdata_iter_valid(exitReasonData
)) {
56 FAIL("Could not find exit data");
58 struct exit_reason_snapshot
*ers
= (struct exit_reason_snapshot
*)kcdata_iter_payload(exitReasonData
);
60 if ( ers
->ers_namespace
!= OS_REASON_DYLD
) {
61 FAIL("eri_namespace (%d) != OS_REASON_DYLD", ers
->ers_namespace
);
63 if ( ers
->ers_code
!= DYLD_EXIT_REASON_OTHER
) {
64 FAIL("eri_code (%lld) != DYLD_EXIT_REASON_OTHER", ers
->ers_code
);
66 kcdata_iter_t iter
= kcdata_iter((void*)corpse_data
, corpse_size
);
68 KCDATA_ITER_FOREACH(iter
) {
69 if (kcdata_iter_type(iter
) == KCDATA_TYPE_NESTED_KCDATA
) {
70 kcdata_iter_t nestedIter
= kcdata_iter(kcdata_iter_payload(iter
), kcdata_iter_size(iter
));
71 if ( kcdata_iter_type(nestedIter
) != KCDATA_BUFFER_BEGIN_OS_REASON
){
74 kcdata_iter_t payloadIter
= kcdata_iter_find_type(nestedIter
, EXIT_REASON_USER_PAYLOAD
);
75 if ( !kcdata_iter_valid(payloadIter
) ) {
76 FAIL("invalid kcdata payload iterator from payload data");
78 const dyld_abort_payload
* dyldInfo
= (dyld_abort_payload
*)kcdata_iter_payload(payloadIter
);
80 if ( dyldInfo
->version
!= 1 ) {
81 FAIL("dyld payload is not version 1");
86 FAIL("Did not find EXIT_REASON_USER_PAYLOAD");