1 #include <sys/kdebug.h>
7 #include <darwintest.h>
9 // From bsd/sys/proc_internal.h
12 T_DECL(exit
, "exit(2) time from syscall start to end", T_META_TYPE_PERF
, T_META_CHECK_LEAKS(NO
)) {
13 _Atomic
static int ended
= 0;
14 dispatch_queue_t spawn_queue
;
16 dt_stat_time_t s
= dt_stat_time_create("time");
18 uint64_t *begin_ts
= malloc(sizeof(uint64_t) * PID_MAX
);
19 if (begin_ts
== NULL
) {
20 T_FAIL("Error allocating timestamp array");
23 ktrace_session_t session
;
24 session
= ktrace_session_create();
25 if (session
== NULL
) {
26 T_FAIL("Error creating ktrace session");
29 ktrace_set_completion_handler(session
, ^{
35 ktrace_set_signal_handler(session
);
37 // We are only interested by the process we launched
38 ktrace_filter_process(session
, "true");
40 ktrace_events_single(session
, (BSDDBG_CODE(DBG_BSD_EXCP_SC
, 1) | DBG_FUNC_START
), ^(ktrace_event_t e
) {
41 pid_t pid
= ktrace_get_pid_for_thread(session
, e
->threadid
);
43 T_FAIL("Invalid pid returned by ktrace_get_pid_for_thread: %d\n", pid
);
45 begin_ts
[pid
] = e
->timestamp
;
48 ktrace_events_single(session
, (BSDDBG_CODE(DBG_BSD_PROC
, BSD_PROC_EXIT
) | DBG_FUNC_END
), ^(ktrace_event_t e
) {
49 pid_t pid
= ktrace_get_pid_for_thread(session
, e
->threadid
);
51 T_FAIL("Invalid pid returned by ktrace_get_pid_for_thread: %d\n", pid
);
53 if (begin_ts
[pid
] == 0) {
56 uint64_t delta
= e
->timestamp
- begin_ts
[pid
];
57 if (!dt_stat_stable(s
)) {
58 dt_stat_mach_time_add(s
, delta
);
62 ktrace_end(session
, 1);
66 int ret
= ktrace_start(session
, dispatch_get_main_queue());
68 T_FAIL("Error starting ktrace");
71 // Spawn processes continuously until the test is over
72 spawn_queue
= dispatch_queue_create("spawn_queue", NULL
);
73 dispatch_async(spawn_queue
, ^(void) {
77 char *args
[] = {"/usr/bin/true", NULL
};
78 int err
= posix_spawn(&pid
, args
[0], NULL
, NULL
, args
, NULL
);
80 T_FAIL("posix_spawn returned %d", err
);
82 waitpid(pid
, &status
, 0);
83 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0)
84 T_FAIL("Child process of posix_spawn failed to run");