]> git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/dyld_abort_payload.dtest/main.cpp
dyld-750.5.tar.gz
[apple/dyld.git] / testing / test-cases / dyld_abort_payload.dtest / main.cpp
1
2 // BUILD: $CC foo.c -dynamiclib -install_name /cant/find/me.dylib -o $BUILD_DIR/libmissing.dylib
3 // BUILD: $CC foo.c -dynamiclib $BUILD_DIR/libmissing.dylib -install_name $RUN_DIR/libMissingDylib.dylib -o $BUILD_DIR/libMissingDylib.dylib
4 // BUILD: $CC emptyMain.c $BUILD_DIR/libMissingDylib.dylib -o $BUILD_DIR/prog_missing_dylib.exe
5 // BUILD: $CC defSymbol.c -dynamiclib -install_name $RUN_DIR/libMissingSymbols.dylib -o $BUILD_DIR/libMissingSymbols.dylib
6 // BUILD: $CC defSymbol.c -dynamiclib -install_name $RUN_DIR/libMissingSymbols.dylib -o $BUILD_DIR/libHasSymbols.dylib -DHAS_SYMBOL
7 // BUILD: $CC useSymbol.c $BUILD_DIR/libHasSymbols.dylib -o $BUILD_DIR/prog_missing_symbol.exe
8 // BUILD: $CXX main.cpp -o $BUILD_DIR/dyld_abort_tests.exe
9
10 // NO_CRASH_LOG: prog_missing_dylib.exe
11 // NO_CRASH_LOG: prog_missing_symbol.exe
12
13 // RUN: ./dyld_abort_tests.exe
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <dlfcn.h>
18 #include <unistd.h>
19 #include <signal.h>
20 #include <spawn.h>
21 #include <errno.h>
22 #include <mach/mach.h>
23 #include <mach/machine.h>
24 #include <err.h>
25 #include <System/sys/reason.h>
26 #include <System/sys/proc_info.h>
27 #include <System/kern/kern_cdata.h>
28 #include <libproc.h>
29 #include <mach-o/dyld_priv.h>
30
31 #include "test_support.h"
32
33
34 void runTest(const char* prog, uint64_t dyldReason, const char* expectedDylibPath, const char* expectedSymbol) {
35 _process process;
36 process.set_executable_path(prog);
37 process.set_crash_handler(^(task_t task) {
38 LOG("Crash for task=%u", task);
39 vm_address_t corpse_data;
40 uint32_t corpse_size;
41 if (task_map_corpse_info(mach_task_self(), task, &corpse_data, &corpse_size) != KERN_SUCCESS) {
42 FAIL("Could not read corpse data");
43 }
44 kcdata_iter_t autopsyData = kcdata_iter((void*)corpse_data, corpse_size);
45 if (!kcdata_iter_valid(autopsyData)) {
46 FAIL("Corpse Data Invalid");
47 }
48 kcdata_iter_t exitReasonData = kcdata_iter_find_type(autopsyData, EXIT_REASON_SNAPSHOT);
49 if (!kcdata_iter_valid(exitReasonData)) {
50 FAIL("Could not find exit data");
51 }
52 struct exit_reason_snapshot *ers = (struct exit_reason_snapshot *)kcdata_iter_payload(exitReasonData);
53
54 if ( ers->ers_namespace != OS_REASON_DYLD ) {
55 FAIL("eri_namespace (%d) != OS_REASON_DYLD", ers->ers_namespace);
56 }
57 if ( ers->ers_code != dyldReason ) {
58 FAIL("eri_code (%llu) != dyldReason (%lld)", ers->ers_code, dyldReason);
59 }
60 kcdata_iter_t iter = kcdata_iter((void*)corpse_data, corpse_size);
61
62 KCDATA_ITER_FOREACH(iter) {
63 if (kcdata_iter_type(iter) == KCDATA_TYPE_NESTED_KCDATA) {
64 kcdata_iter_t nestedIter = kcdata_iter(kcdata_iter_payload(iter), kcdata_iter_size(iter));
65 if ( kcdata_iter_type(nestedIter) != KCDATA_BUFFER_BEGIN_OS_REASON ){
66 return;
67 }
68 kcdata_iter_t payloadIter = kcdata_iter_find_type(nestedIter, EXIT_REASON_USER_PAYLOAD);
69 if ( !kcdata_iter_valid(payloadIter) ) {
70 FAIL("invalid kcdata payload iterator from payload data");
71 }
72 const dyld_abort_payload* dyldInfo = (dyld_abort_payload*)kcdata_iter_payload(payloadIter);
73
74 if ( dyldInfo->version != 1 ) {
75 FAIL("dyld payload is not version 1");
76 }
77
78 if ( (dyldInfo->flags & 1) == 0 ) {
79 FAIL("dyld flags should have low bit set to indicate process terminated during launch");
80 }
81
82 if ( expectedDylibPath != NULL ) {
83 if ( dyldInfo->targetDylibPathOffset != 0 ) {
84 const char* targetDylib = (char*)dyldInfo + dyldInfo->targetDylibPathOffset;
85 if ( strstr(targetDylib, expectedDylibPath) == NULL ) {
86 FAIL("dylib path (%s) not what expected (%s)", targetDylib, expectedDylibPath);
87 }
88 } else {
89 FAIL("dylib path (%s) not provided by dyld", expectedDylibPath);
90 }
91 }
92
93 if ( expectedSymbol != NULL ) {
94 if ( dyldInfo->targetDylibPathOffset != 0 ) {
95 const char* missingSymbol = (char*)dyldInfo + dyldInfo->symbolOffset;
96 if ( strcmp(expectedSymbol, missingSymbol) != 0 ) {
97 FAIL("symbol (%s) not what expected (%s)", missingSymbol, expectedSymbol);
98 }
99 } else {
100 FAIL("symbol (%s) not provided by dyld", expectedSymbol);
101 }
102 }
103 PASS("Success");
104 }
105 }
106 FAIL("Did not find EXIT_REASON_USER_PAYLOAD");
107 });
108 process.launch();
109 }
110
111
112 int main(int argc, const char* argv[], const char* envp[], const char* apple[]) {
113 // test launch program with missing library
114 runTest("./prog_missing_dylib.exe", DYLD_EXIT_REASON_DYLIB_MISSING, "/cant/find/me.dylib", NULL);
115 // runTest("./prog_missing_symbol.exe", DYLD_EXIT_REASON_SYMBOL_MISSING, "libMissingSymbols.dylib", "_slipperySymbol");
116 PASS("Success");
117 }
118