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
6 // RUN: $SUDO ./dyld_process_info.exe
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>
24 #include "dyld_test.h"
26 static void inspectProcess(task_t task
, bool launchedSuspended
, bool expectCF
, bool forceIOSMac
)
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");
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");
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");
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()");
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
)
58 if ( strstr(path
, "/linksWithCF.exe") != NULL
)
60 if ( strstr(path
, "/dyld_process_info.exe") != NULL
)
62 if ( strstr(path
, "/CoreFoundation.framework/") != NULL
)
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");
68 T_EXPECT_TRUE(foundCF
, "CF should be in the image list");
71 _dyld_process_info_release(info
);
74 static void launchTest(bool launchOtherArch
, bool launchSuspended
, bool forceIOSMac
)
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"); }
81 // wait until process is up and has suspended itself
82 struct task_basic_info info
;
84 unsigned count
= TASK_BASIC_INFO_COUNT
;
85 kern_return_t kr
= task_info(task
, TASK_BASIC_INFO
, (task_info_t
)&info
, &count
);
87 } while ( info
.suspend_count
== 0 );
89 inspectProcess(task
, launchSuspended
, !launchSuspended
, forceIOSMac
);
90 int r
= kill(pid
, SIGKILL
);
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);
106 inspectProcess(mach_task_self(), false, false, false);