dyld-733.8.tar.gz
[apple/dyld.git] / testing / test-cases / dyld_process_info.dtest / main.c
1
2 // BUILD: $CC linksWithCF.c -o $BUILD_DIR/linksWithCF.exe -framework CoreFoundation
3 // BUILD: $CC main.c -o $BUILD_DIR/dyld_process_info.exe -ldarwintest
4 // BUILD: $TASK_FOR_PID_ENABLE $BUILD_DIR/dyld_process_info.exe
5
6 // RUN: $SUDO ./dyld_process_info.exe
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <dlfcn.h>
11 #include <unistd.h>
12 #include <signal.h>
13 #include <spawn.h>
14 #include <errno.h>
15 #include <sys/uio.h>
16 #include <sys/wait.h>
17 #include <sys/types.h>
18 #include <mach/mach.h>
19 #include <mach/machine.h>
20 #include <mach-o/dyld_priv.h>
21 #include <mach-o/dyld_process_info.h>
22 #include <Availability.h>
23
24 #include "dyld_test.h"
25
26 static void inspectProcess(task_t task, bool launchedSuspended, bool expectCF, bool forceIOSMac)
27 {
28 kern_return_t result;
29 dyld_process_info info = _dyld_process_info_create(task, 0, &result);
30 T_EXPECT_MACH_SUCCESS(result, "dyld_process_info() should succeed");
31 T_ASSERT_NOTNULL(info, "dyld_process_info(task, 0) alwats return a value");
32
33 dyld_process_state_info stateInfo;
34 bzero(&stateInfo, sizeof(stateInfo));
35 _dyld_process_info_get_state(info, &stateInfo);
36 T_EXPECT_EQ_UINT((stateInfo.dyldState == dyld_process_state_not_started), launchedSuspended, "If launchSuspended then stateInfo.dyldState shoould be dyld_process_state_not_started");
37 if ( !launchedSuspended ) {
38 T_EXPECT_GE_UCHAR(stateInfo.dyldState, dyld_process_state_libSystem_initialized, "libSystem should be initalized by now");
39 T_EXPECT_GT_UINT(stateInfo.imageCount, 0, "image count should be > 0");
40 T_EXPECT_GT_UINT(stateInfo.initialImageCount, 0, "initial image count should be > 0");
41 T_EXPECT_GE_UINT(stateInfo.imageCount, stateInfo.initialImageCount, "image count should be >= initial image count");
42 }
43
44 if (launchedSuspended) {
45 T_EXPECT_EQ_UINT(_dyld_process_info_get_platform(info), 0, "_dyld_process_info_get_platform() should be 0 for launchSuspended processes");
46 } else if (forceIOSMac) {
47 T_EXPECT_EQ_UINT(_dyld_process_info_get_platform(info), PLATFORM_IOSMAC, "_dyld_process_info_get_platform() should be PLATFORM_IOSMAC");
48 } else {
49 T_EXPECT_EQ_UINT(_dyld_process_info_get_platform(info), dyld_get_active_platform(), "_dyld_process_info_get_platform() should be the same dyld_get_active_platform()");
50 }
51
52 __block bool foundDyld = false;
53 __block bool foundMain = false;
54 __block bool foundCF = false;
55 _dyld_process_info_for_each_image(info, ^(uint64_t machHeaderAddress, const uuid_t uuid, const char* path) {
56 if ( strstr(path, "/dyld") != NULL )
57 foundDyld = true;
58 if ( strstr(path, "/linksWithCF.exe") != NULL )
59 foundMain = true;
60 if ( strstr(path, "/dyld_process_info.exe") != NULL )
61 foundMain = true;
62 if ( strstr(path, "/CoreFoundation.framework/") != NULL )
63 foundCF = true;
64 });
65 T_EXPECT_TRUE(foundDyld, "dyld should always be in the image list");
66 T_EXPECT_TRUE(foundMain, "The main executable should always be in the image list");
67 if (expectCF) {
68 T_EXPECT_TRUE(foundCF, "CF should be in the image list");
69 }
70
71 _dyld_process_info_release(info);
72 }
73
74 static void launchTest(bool launchOtherArch, bool launchSuspended, bool forceIOSMac)
75 {
76 if (forceIOSMac) { setenv("DYLD_FORCE_PLATFORM", "6", 1); }
77 pid_t pid = T_POSIXSPAWN_ASSERT(launchSuspended, launchOtherArch, INSTALL_PATH "/linksWithCF.exe");
78 task_t task = T_TASK_FOR_PID_ASSERT(pid);
79 if (forceIOSMac) { unsetenv("DYLD_FORCE_PLATFORM"); }
80
81 // wait until process is up and has suspended itself
82 struct task_basic_info info;
83 do {
84 unsigned count = TASK_BASIC_INFO_COUNT;
85 kern_return_t kr = task_info(task, TASK_BASIC_INFO, (task_info_t)&info, &count);
86 usleep(10000);
87 } while ( info.suspend_count == 0 );
88
89 inspectProcess(task, launchSuspended, !launchSuspended, forceIOSMac);
90 int r = kill(pid, SIGKILL);
91 waitpid(pid, &r, 0);
92 }
93
94 T_DECL_DYLD(dyld_process_info, "Test basic dyld_process_info functionality", T_META_ASROOT(true)) {
95 launchTest(false, false, false);
96 launchTest(false, true, false);
97 #if __MAC_OS_X_VERSION_MIN_REQUIRED
98 // FIXME: Reenable these ones i386 is turned back on for simulators
99 //launchTest(true, false, false);
100 //launchTest(true, true, false);
101 launchTest(false, false, true);
102 launchTest(false, true, true);
103 //FIXME: This functionality is broken, but it is an edge case no one should ever hit
104 //launchTest(true, true, true);
105 #endif
106 inspectProcess(mach_task_self(), false, false, false);
107 }