1*043036a2SApple OSS Distributions // Copyright (c) 2020 Apple Inc. All rights reserved.
2*043036a2SApple OSS Distributions
3*043036a2SApple OSS Distributions #include <darwintest.h>
4*043036a2SApple OSS Distributions #include <darwintest_utils.h>
5*043036a2SApple OSS Distributions #include <dispatch/dispatch.h>
6*043036a2SApple OSS Distributions #include <inttypes.h>
7*043036a2SApple OSS Distributions #include <ktrace/session.h>
8*043036a2SApple OSS Distributions #include <ktrace/private.h>
9*043036a2SApple OSS Distributions #include <kperf/kperf.h>
10*043036a2SApple OSS Distributions #include <stdlib.h>
11*043036a2SApple OSS Distributions #include <sys/kdebug.h>
12*043036a2SApple OSS Distributions #include <sys/kdebug_private.h>
13*043036a2SApple OSS Distributions #include <sys/sysctl.h>
14*043036a2SApple OSS Distributions #include <stdint.h>
15*043036a2SApple OSS Distributions
16*043036a2SApple OSS Distributions #include "ktrace_helpers.h"
17*043036a2SApple OSS Distributions #include "test_utils.h"
18*043036a2SApple OSS Distributions #include "ktrace_meta.h"
19*043036a2SApple OSS Distributions
20*043036a2SApple OSS Distributions static const uint32_t frame_eventid = KDBG_EVENTID(DBG_BSD,
21*043036a2SApple OSS Distributions DBG_BSD_KDEBUG_TEST, 1);
22*043036a2SApple OSS Distributions
23*043036a2SApple OSS Distributions static ktrace_session_t
future_events_session(void)24*043036a2SApple OSS Distributions future_events_session(void)
25*043036a2SApple OSS Distributions {
26*043036a2SApple OSS Distributions ktrace_session_t ktsess = ktrace_session_create();
27*043036a2SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(ktsess, "failed to create session");
28*043036a2SApple OSS Distributions
29*043036a2SApple OSS Distributions ktrace_events_single(ktsess, KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 0),
30*043036a2SApple OSS Distributions ^(struct trace_point *tp __unused) {
31*043036a2SApple OSS Distributions T_FAIL("saw future test event from IOP");
32*043036a2SApple OSS Distributions });
33*043036a2SApple OSS Distributions ktrace_events_single(ktsess, frame_eventid, ^(struct trace_point *tp) {
34*043036a2SApple OSS Distributions if (tp->debugid & DBG_FUNC_START) {
35*043036a2SApple OSS Distributions T_LOG("saw start event");
36*043036a2SApple OSS Distributions } else {
37*043036a2SApple OSS Distributions T_LOG("saw event traced after trying to trace future event, ending");
38*043036a2SApple OSS Distributions ktrace_end(ktsess, 1);
39*043036a2SApple OSS Distributions }
40*043036a2SApple OSS Distributions });
41*043036a2SApple OSS Distributions
42*043036a2SApple OSS Distributions ktrace_set_collection_interval(ktsess, 100);
43*043036a2SApple OSS Distributions return ktsess;
44*043036a2SApple OSS Distributions }
45*043036a2SApple OSS Distributions
46*043036a2SApple OSS Distributions T_DECL(future_iop_events,
47*043036a2SApple OSS Distributions "make sure IOPs cannot trace events in the future while live tracing",
48*043036a2SApple OSS Distributions T_META_TAG_VM_NOT_PREFERRED)
49*043036a2SApple OSS Distributions {
50*043036a2SApple OSS Distributions start_controlling_ktrace();
51*043036a2SApple OSS Distributions ktrace_session_t ktsess = future_events_session();
52*043036a2SApple OSS Distributions ktrace_set_completion_handler(ktsess, ^{
53*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
54*043036a2SApple OSS Distributions T_END;
55*043036a2SApple OSS Distributions });
56*043036a2SApple OSS Distributions
57*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
58*043036a2SApple OSS Distributions "start tracing");
59*043036a2SApple OSS Distributions kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
60*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_FUTURE_TIMESTAMP, "induce future times");
61*043036a2SApple OSS Distributions kdebug_trace(frame_eventid | DBG_FUNC_END, 0, 0, 0, 0);
62*043036a2SApple OSS Distributions
63*043036a2SApple OSS Distributions dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC),
64*043036a2SApple OSS Distributions dispatch_get_main_queue(), ^{
65*043036a2SApple OSS Distributions T_FAIL("ending tracing after timeout");
66*043036a2SApple OSS Distributions ktrace_end(ktsess, 0);
67*043036a2SApple OSS Distributions });
68*043036a2SApple OSS Distributions
69*043036a2SApple OSS Distributions dispatch_main();
70*043036a2SApple OSS Distributions }
71*043036a2SApple OSS Distributions
72*043036a2SApple OSS Distributions T_DECL(future_iop_events_disabled,
73*043036a2SApple OSS Distributions "make sure IOPs cannot trace events in the future after disabling tracing",
74*043036a2SApple OSS Distributions T_META_TAG_VM_NOT_PREFERRED)
75*043036a2SApple OSS Distributions {
76*043036a2SApple OSS Distributions start_controlling_ktrace();
77*043036a2SApple OSS Distributions ktrace_session_t ktsess = future_events_session();
78*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_configure(ktsess), "configure tracing");
79*043036a2SApple OSS Distributions
80*043036a2SApple OSS Distributions kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
81*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_FUTURE_TIMESTAMP, "induce future times");
82*043036a2SApple OSS Distributions kdebug_trace(frame_eventid | DBG_FUNC_END, 0, 0, 0, 0);
83*043036a2SApple OSS Distributions
84*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_disable_configured(ktsess),
85*043036a2SApple OSS Distributions "disable tracing");
86*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
87*043036a2SApple OSS Distributions
88*043036a2SApple OSS Distributions ktsess = future_events_session();
89*043036a2SApple OSS Distributions T_QUIET;
90*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_set_use_existing(ktsess), "use existing trace");
91*043036a2SApple OSS Distributions ktrace_set_completion_handler(ktsess, ^{
92*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
93*043036a2SApple OSS Distributions T_END;
94*043036a2SApple OSS Distributions });
95*043036a2SApple OSS Distributions
96*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
97*043036a2SApple OSS Distributions "start tracing existing session");
98*043036a2SApple OSS Distributions
99*043036a2SApple OSS Distributions dispatch_main();
100*043036a2SApple OSS Distributions }
101*043036a2SApple OSS Distributions
102*043036a2SApple OSS Distributions T_DECL(iop_events_disable,
103*043036a2SApple OSS Distributions "make sure IOP events are flushed before disabling trace",
104*043036a2SApple OSS Distributions T_META_TAG_VM_PREFERRED)
105*043036a2SApple OSS Distributions {
106*043036a2SApple OSS Distributions start_controlling_ktrace();
107*043036a2SApple OSS Distributions ktrace_session_t ktsess = future_events_session();
108*043036a2SApple OSS Distributions
109*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_SETUP_IOP, "setup sync flush IOP");
110*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_configure(ktsess), "configure tracing");
111*043036a2SApple OSS Distributions
112*043036a2SApple OSS Distributions kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
113*043036a2SApple OSS Distributions
114*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_disable_configured(ktsess),
115*043036a2SApple OSS Distributions "disable tracing");
116*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
117*043036a2SApple OSS Distributions
118*043036a2SApple OSS Distributions ktsess = ktrace_session_create();
119*043036a2SApple OSS Distributions T_QUIET; T_WITH_ERRNO;
120*043036a2SApple OSS Distributions T_ASSERT_NOTNULL(ktsess, "create session");
121*043036a2SApple OSS Distributions
122*043036a2SApple OSS Distributions ktrace_events_single(ktsess,
123*043036a2SApple OSS Distributions KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 0xff),
124*043036a2SApple OSS Distributions ^(struct trace_point *tp __unused) {
125*043036a2SApple OSS Distributions T_PASS("saw IOP event from sync flush");
126*043036a2SApple OSS Distributions });
127*043036a2SApple OSS Distributions
128*043036a2SApple OSS Distributions T_QUIET;
129*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_set_use_existing(ktsess), "use existing trace");
130*043036a2SApple OSS Distributions ktrace_set_completion_handler(ktsess, ^{
131*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
132*043036a2SApple OSS Distributions T_END;
133*043036a2SApple OSS Distributions });
134*043036a2SApple OSS Distributions
135*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
136*043036a2SApple OSS Distributions "start tracing existing session");
137*043036a2SApple OSS Distributions
138*043036a2SApple OSS Distributions dispatch_main();
139*043036a2SApple OSS Distributions }
140*043036a2SApple OSS Distributions
141*043036a2SApple OSS Distributions T_DECL(past_coproc_events,
142*043036a2SApple OSS Distributions "make sure past events from coprocessors log a TRACE_PAST_EVENTS event",
143*043036a2SApple OSS Distributions T_META_TAG_VM_PREFERRED)
144*043036a2SApple OSS Distributions {
145*043036a2SApple OSS Distributions start_controlling_ktrace();
146*043036a2SApple OSS Distributions ktrace_session_t ktsess = future_events_session();
147*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_configure(ktsess), "configure tracing");
148*043036a2SApple OSS Distributions
149*043036a2SApple OSS Distributions kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
150*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_PAST_EVENT, "induce past events");
151*043036a2SApple OSS Distributions kdebug_trace(frame_eventid | DBG_FUNC_END, 0, 0, 0, 0);
152*043036a2SApple OSS Distributions
153*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_disable_configured(ktsess), "disable tracing");
154*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
155*043036a2SApple OSS Distributions
156*043036a2SApple OSS Distributions ktsess = future_events_session();
157*043036a2SApple OSS Distributions T_QUIET;
158*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_set_use_existing(ktsess), "use existing trace");
159*043036a2SApple OSS Distributions __block bool saw_past_event = false;
160*043036a2SApple OSS Distributions ktrace_events_single(ktsess, TRACE_PAST_EVENTS,
161*043036a2SApple OSS Distributions ^(__unused ktrace_event_t event) {
162*043036a2SApple OSS Distributions saw_past_event = true;
163*043036a2SApple OSS Distributions });
164*043036a2SApple OSS Distributions ktrace_set_completion_handler(ktsess, ^{
165*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
166*043036a2SApple OSS Distributions T_EXPECT_TRUE(saw_past_event, "saw past event");
167*043036a2SApple OSS Distributions T_END;
168*043036a2SApple OSS Distributions });
169*043036a2SApple OSS Distributions
170*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
171*043036a2SApple OSS Distributions "start tracing existing session");
172*043036a2SApple OSS Distributions
173*043036a2SApple OSS Distributions dispatch_main();
174*043036a2SApple OSS Distributions }
175*043036a2SApple OSS Distributions
176*043036a2SApple OSS Distributions static void
expect_convert_between_abs_cont(bool abs_to_cont)177*043036a2SApple OSS Distributions expect_convert_between_abs_cont(bool abs_to_cont)
178*043036a2SApple OSS Distributions {
179*043036a2SApple OSS Distributions uint64_t cur_abs_time, cur_cont_time;
180*043036a2SApple OSS Distributions kern_return_t kr = mach_get_times(&cur_abs_time, &cur_cont_time, NULL);
181*043036a2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_get_times");
182*043036a2SApple OSS Distributions bool hasnt_slept = cur_abs_time == cur_cont_time;
183*043036a2SApple OSS Distributions if (hasnt_slept) {
184*043036a2SApple OSS Distributions T_LOG("system hasn't slept, so continuous and absolute times are equal");
185*043036a2SApple OSS Distributions T_LOG("this test cannot ensure time conversions are done properly");
186*043036a2SApple OSS Distributions } else {
187*043036a2SApple OSS Distributions T_LOG("system has slept, times differ by %llu",
188*043036a2SApple OSS Distributions cur_cont_time - cur_abs_time);
189*043036a2SApple OSS Distributions }
190*043036a2SApple OSS Distributions
191*043036a2SApple OSS Distributions start_controlling_ktrace();
192*043036a2SApple OSS Distributions ktrace_session_t ktsess = ktrace_session_create();
193*043036a2SApple OSS Distributions ktrace_set_collection_interval(ktsess, 100);
194*043036a2SApple OSS Distributions if (abs_to_cont) {
195*043036a2SApple OSS Distributions ktrace_set_continuous_timestamps(ktsess, true);
196*043036a2SApple OSS Distributions }
197*043036a2SApple OSS Distributions
198*043036a2SApple OSS Distributions __block bool found_abs_event = false;
199*043036a2SApple OSS Distributions __block bool found_cont_event = false;
200*043036a2SApple OSS Distributions const uint32_t abs_eventid = KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 0);
201*043036a2SApple OSS Distributions ktrace_events_single(ktsess, abs_eventid, ^(struct trace_point *tp) {
202*043036a2SApple OSS Distributions found_abs_event = true;
203*043036a2SApple OSS Distributions uint64_t arg_timestamp = (tp->arg1 & UINT32_MAX) | (tp->arg2 << 32);
204*043036a2SApple OSS Distributions if (abs_to_cont) {
205*043036a2SApple OSS Distributions if (hasnt_slept) {
206*043036a2SApple OSS Distributions T_MAYFAIL;
207*043036a2SApple OSS Distributions }
208*043036a2SApple OSS Distributions T_EXPECT_NE(tp->timestamp, arg_timestamp,
209*043036a2SApple OSS Distributions "timestamp from absolute time IOP should be converted");
210*043036a2SApple OSS Distributions } else {
211*043036a2SApple OSS Distributions T_EXPECT_EQ(tp->timestamp, arg_timestamp,
212*043036a2SApple OSS Distributions "timestamp from absolute time IOP should not be converted");
213*043036a2SApple OSS Distributions }
214*043036a2SApple OSS Distributions if (found_cont_event && found_abs_event) {
215*043036a2SApple OSS Distributions ktrace_end(ktsess, 1);
216*043036a2SApple OSS Distributions }
217*043036a2SApple OSS Distributions });
218*043036a2SApple OSS Distributions
219*043036a2SApple OSS Distributions const uint32_t cont_eventid = KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 1);
220*043036a2SApple OSS Distributions ktrace_events_single(ktsess, cont_eventid, ^(struct trace_point *tp) {
221*043036a2SApple OSS Distributions found_cont_event = true;
222*043036a2SApple OSS Distributions uint64_t arg_timestamp = (tp->arg1 & UINT32_MAX) | (tp->arg2 << 32);
223*043036a2SApple OSS Distributions if (abs_to_cont) {
224*043036a2SApple OSS Distributions T_EXPECT_EQ(tp->timestamp, arg_timestamp,
225*043036a2SApple OSS Distributions "timestamp from continuous time coprocessor should not be "
226*043036a2SApple OSS Distributions "converted");
227*043036a2SApple OSS Distributions } else {
228*043036a2SApple OSS Distributions if (hasnt_slept) {
229*043036a2SApple OSS Distributions T_MAYFAIL;
230*043036a2SApple OSS Distributions }
231*043036a2SApple OSS Distributions T_EXPECT_NE(tp->timestamp, arg_timestamp,
232*043036a2SApple OSS Distributions "timestamp from continuous time coprocessor should be "
233*043036a2SApple OSS Distributions "converted");
234*043036a2SApple OSS Distributions }
235*043036a2SApple OSS Distributions if (found_cont_event && found_abs_event) {
236*043036a2SApple OSS Distributions ktrace_end(ktsess, 1);
237*043036a2SApple OSS Distributions }
238*043036a2SApple OSS Distributions });
239*043036a2SApple OSS Distributions
240*043036a2SApple OSS Distributions ktrace_set_completion_handler(ktsess, ^{
241*043036a2SApple OSS Distributions T_EXPECT_TRUE(found_abs_event, "absolute time event present");
242*043036a2SApple OSS Distributions T_EXPECT_TRUE(found_cont_event, "continuous time event present");
243*043036a2SApple OSS Distributions ktrace_session_destroy(ktsess);
244*043036a2SApple OSS Distributions T_END;
245*043036a2SApple OSS Distributions });
246*043036a2SApple OSS Distributions
247*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_SETUP_IOP, "setup sync flush IOP");
248*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_SETUP_COPROCESSOR, "setup coprocessor");
249*043036a2SApple OSS Distributions
250*043036a2SApple OSS Distributions T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
251*043036a2SApple OSS Distributions "start tracing");
252*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_ABSOLUTE_TIMESTAMP, "induce absolute times");
253*043036a2SApple OSS Distributions assert_kdebug_test(KDTEST_CONTINUOUS_TIMESTAMP, "induce continuous times");
254*043036a2SApple OSS Distributions T_QUIET;
255*043036a2SApple OSS Distributions T_EXPECT_EQ(kdebug_using_continuous_time(), abs_to_cont,
256*043036a2SApple OSS Distributions "should be using continuous time");
257*043036a2SApple OSS Distributions
258*043036a2SApple OSS Distributions dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC),
259*043036a2SApple OSS Distributions dispatch_get_main_queue(), ^{
260*043036a2SApple OSS Distributions T_LOG("ending tracing after timeout");
261*043036a2SApple OSS Distributions ktrace_end(ktsess, 0);
262*043036a2SApple OSS Distributions });
263*043036a2SApple OSS Distributions }
264*043036a2SApple OSS Distributions
265*043036a2SApple OSS Distributions T_DECL(absolute_to_continuous_iop,
266*043036a2SApple OSS Distributions "expect IOPs issuing absolute times show up as continuous in the stream",
267*043036a2SApple OSS Distributions T_META_TAG_VM_PREFERRED)
268*043036a2SApple OSS Distributions {
269*043036a2SApple OSS Distributions expect_convert_between_abs_cont(true);
270*043036a2SApple OSS Distributions dispatch_main();
271*043036a2SApple OSS Distributions }
272*043036a2SApple OSS Distributions
273*043036a2SApple OSS Distributions T_DECL(continuous_to_absolute_coproc,
274*043036a2SApple OSS Distributions "expect IOPs issuing absolute times show up as continuous in the stream",
275*043036a2SApple OSS Distributions T_META_TAG_VM_PREFERRED)
276*043036a2SApple OSS Distributions {
277*043036a2SApple OSS Distributions expect_convert_between_abs_cont(false);
278*043036a2SApple OSS Distributions dispatch_main();
279*043036a2SApple OSS Distributions }
280