3 #include <dispatch/dispatch.h>
8 #include <sys/syscall.h>
10 #include <mach/mach_time.h>
11 #include <sys/stackshot.h>
12 #include <sys/types.h>
13 #include <kern/debug.h>
17 #include <kern/kcdata.h>
19 #define STACKSHOT_TAILSPIN (0x80000)
22 stackshot_get_mach_absolute_time(void *buffer
, uint32_t size
)
24 kcdata_iter_t iter
= kcdata_iter_find_type(kcdata_iter(buffer
, size
), KCDATA_TYPE_MACH_ABSOLUTE_TIME
);
25 if (!kcdata_iter_valid(iter
) || kcdata_iter_size(iter
) < sizeof(uint64_t)) {
26 fprintf(stderr
, "bad kcdata\n");
29 return *(uint64_t *)kcdata_iter_payload(iter
);
32 static void usage(char **argv
)
34 fprintf (stderr
, "usage: %s [-d] [-t] >file\n", argv
[0]);
35 fprintf (stderr
, " -d : take delta stackshot\n");
36 fprintf (stderr
, " -b : get bootprofile\n");
37 fprintf (stderr
, " -t : enable tailspin mode\n");
38 fprintf (stderr
, " -s : fork a sleep process\n");
39 fprintf (stderr
, " -L : disable loadinfo\n");
40 fprintf (stderr
, " -k : active kernel threads only\n");
41 fprintf (stderr
, " -I : disable io statistics\n");
42 fprintf (stderr
, " -p PID : target a pid\n");
54 execlp("sleep", "sleep", "30", NULL
);
61 int main(int argc
, char **argv
) {
64 uint32_t active_kernel_threads_only
= 0;
65 uint32_t tailspin
= 0;
66 uint32_t bootprofile
= 0;
67 uint32_t loadinfo
= STACKSHOT_SAVE_LOADINFO
| STACKSHOT_SAVE_KEXT_LOADINFO
;
68 boolean_t delta
= FALSE
;
69 boolean_t sleep
= FALSE
;
73 while ((c
= getopt(argc
, argv
, "IkbLdtsp:")) != EOF
) {
76 iostats
|= STACKSHOT_NO_IO_STATS
;
79 active_kernel_threads_only
|= STACKSHOT_ACTIVE_KERNEL_THREADS_ONLY
;
80 loadinfo
&= ~STACKSHOT_SAVE_LOADINFO
;
83 bootprofile
|= STACKSHOT_GET_BOOT_PROFILE
;
89 tailspin
|= STACKSHOT_TAILSPIN
;
113 void * config
= stackshot_config_create();
115 perror("stackshot_config_create");
118 uint32_t flags
= loadinfo
| STACKSHOT_SAVE_IMP_DONATION_PIDS
| STACKSHOT_GET_DQ
| STACKSHOT_KCDATA_FORMAT
|
119 tailspin
| bootprofile
| active_kernel_threads_only
| iostats
;
121 int err
= stackshot_config_set_flags(config
, flags
);
123 perror("stackshot_config_set_flags");
128 int err
= stackshot_config_set_pid(config
, pid
);
130 perror("stackshot_config_set_flags");
135 err
= stackshot_capture_with_config(config
);
137 perror("stackshot_capture_with_config");
141 void *buf
= stackshot_config_get_stackshot_buffer(config
);
143 perror("stackshot_config_get_stackshot_buffer");
147 uint32_t size
= stackshot_config_get_stackshot_size(config
);
150 // output the original somewhere?
152 uint64_t time
= stackshot_get_mach_absolute_time(buf
, size
);
154 err
= stackshot_config_dealloc_buffer(config
);
157 flags
|= STACKSHOT_COLLECT_DELTA_SNAPSHOT
;
158 int err
= stackshot_config_set_flags(config
, flags
);
160 perror("stackshot_config_set_flags");
164 err
= stackshot_config_set_delta_timestamp(config
, time
);
166 perror("stackshot_config_delta_timestamp");
175 err
= stackshot_capture_with_config(config
);
177 perror("stackshot_capture_with_config");
181 buf
= stackshot_config_get_stackshot_buffer(config
);
183 perror("stackshot_config_get_stackshot_buffer");
187 size
= stackshot_config_get_stackshot_size(config
);
191 fwrite(buf
, size
, 1, stdout
);