1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //
6 // The ABI-stable entry points used by trace instrumentation libraries.
7 //
8 // These functions are used to write trace records into the trace buffer
9 // associated with a trace context.
10 //
11 // Writing trace records is intended to be very fast but the cost varies
12 // depending on the size and complexity of the event and any arguments
13 // which are associated with it.
14 //
15 // At this time, there exists only one trace context, the engine's trace context,
16 // which can be acquired and released using the functions in
17 // <trace-engine/instrumentation.h>. In the future, this API may be extended
18 // to support trace contexts with different scopes.
19 //
20 // Client code shouldn't be using these APIs directly.
21 // See <trace/event.h> for instrumentation macros.
22 //
23
24 #pragma once
25
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include <string.h>
29
30 #include <zircon/assert.h>
31 #include <zircon/compiler.h>
32 #include <zircon/syscalls/object.h>
33 #include <zircon/types.h>
34
35 #include <trace-engine/types.h>
36
37 __BEGIN_CDECLS
38
39 // Opaque type representing a trace context.
40 // Most functions in this header require a valid trace context to operate.
41 typedef struct trace_context trace_context_t;
42
43 // Opaque type representing a trace context that is held for prolonged
44 // periods of time.
45 typedef struct trace_prolonged_context trace_prolonged_context_t;
46
47 // Returns true if tracing of the specified category has been enabled.
48 //
49 // Use |trace_context_register_category_literal()| if you intend to immediately
50 // write a record into the trace buffer after checking the category.
51 //
52 // |context| must be a valid trace context reference.
53 // |category_literal| must be a null-terminated static string constant.
54 //
55 // This function is thread-safe.
56 bool trace_context_is_category_enabled(
57 trace_context_t* context,
58 const char* category_literal);
59
60 // Registers a copy of a string into the string table.
61 //
62 // Writes a string record into the trace buffer if the string was added to the
63 // string table. If the string table is full, returns an inline string reference.
64 //
65 // |context| must be a valid trace context reference.
66 // |string| must be the string to register.
67 // |length| must be the length of the string.
68 // |out_ref| points to where the registered string reference should be returned.
69 //
70 // This function is thread-safe.
71 void trace_context_register_string_copy(
72 trace_context_t* context,
73 const char* string, size_t length,
74 trace_string_ref_t* out_ref);
75
76 // Registers a copy of a string and returns its string ref.
77 // Helper for |trace_context_register_thread()|.
trace_context_make_registered_string_copy(trace_context_t * context,const char * string,size_t length)78 static inline trace_string_ref_t trace_context_make_registered_string_copy(
79 trace_context_t* context,
80 const char* string, size_t length) {
81 trace_string_ref_t ref;
82 trace_context_register_string_copy(context, string, length, &ref);
83 return ref;
84 }
85
86 // Registers a string literal into the string table keyed by its address in memory.
87 //
88 // The trace context caches the string so that subsequent registrations using
89 // the same memory address may return the same indexed string reference if
90 // found in the cache.
91 //
92 // Writes a string record into the trace buffer if the string was added to the
93 // string table. If the string table is full, returns an inline string reference.
94 //
95 // |context| must be a valid trace context reference.
96 // |string_literal| must be a null-terminated static string constant.
97 // |out_ref| points to where the registered string reference should be returned.
98 //
99 // This function is thread-safe.
100 void trace_context_register_string_literal(
101 trace_context_t* context,
102 const char* string_literal,
103 trace_string_ref_t* out_ref);
104
105 // Registers a string literal and returns its string ref.
106 // Helper for |trace_context_register_string_literal()|.
trace_context_make_registered_string_literal(trace_context_t * context,const char * string_literal)107 static inline trace_string_ref_t trace_context_make_registered_string_literal(
108 trace_context_t* context,
109 const char* string_literal) {
110 trace_string_ref_t ref;
111 trace_context_register_string_literal(context, string_literal, &ref);
112 return ref;
113 }
114
115 // Registers a category into the string table, if it is enabled, keyed by its
116 // address in memory.
117 //
118 // The trace context caches the string so that subsequent registrations using
119 // the same memory address may return the same indexed string reference if
120 // found in the cache.
121 //
122 // Writes a string record into the trace buffer if the category was added to the
123 // string table. If the string table is full, returns an inline string reference.
124 //
125 // |context| must be a valid trace context reference.
126 // |category_literal| must be a null-terminated static string constant.
127 // |out_ref| points to where the registered string reference should be returned.
128 //
129 // Returns true and registers the string if the category is enabled, otherwise
130 // returns false and does not modify |*out_ref|.
131 //
132 // This function is thread-safe.
133 bool trace_context_register_category_literal(
134 trace_context_t* context,
135 const char* category_literal,
136 trace_string_ref_t* out_ref);
137
138 // Registers the current thread into the thread table.
139 //
140 // Writes a process and/or thread kernel object record into the trace buffer if
141 // the process and/or thread have not previously been described. Writes a
142 // thread record into the trace buffer if the thread was added to the thread table.
143 //
144 // If the thread table is full, returns an inline thread reference.
145 //
146 // |context| must be a valid trace context reference.
147 // |out_ref| points to where the registered thread reference should be returned.
148 //
149 // This function is thread-safe.
150 void trace_context_register_current_thread(
151 trace_context_t* context,
152 trace_thread_ref_t* out_ref);
153
154 // Registers the virtual thread into the thread table.
155 //
156 // Writes a thread record into the trace buffer if the virtual thread was added
157 // to the thread table.
158 //
159 // If the thread table is full, returns an inline thread reference.
160 //
161 // |context| must be a valid trace context reference.
162 // |process_koid| is the koid of the process which contains the thread.
163 // If ZX_KOID_INVALID is passed, the koid of the current process is used.
164 // |vthread_literal| must be a null-terminated static string constant.
165 // |vthread_id| is the id of the virtual thread to register.
166 // |out_ref| points to where the registered thread reference should be returned.
167 //
168 // This function is thread-safe.
169 void trace_context_register_vthread(
170 trace_context_t* context,
171 zx_koid_t process_koid,
172 const char* vthread_literal,
173 trace_vthread_id_t vthread_id,
174 trace_thread_ref_t* out_ref);
175
176 // Registers the specified thread into the thread table.
177 //
178 // Writes a thread record into the trace buffer if the thread was added to the
179 // thread table.
180 //
181 // If the thread table is full, returns an inline thread reference.
182 //
183 // Unlike |trace_context_register_current_thread()|, the caller is responsible for
184 // writing a process and/or thread kernel object record into the trace buffer
185 // if the process and/or thread have not previously been described.
186 //
187 // |context| must be a valid trace context reference.
188 // |process_koid| is the koid of the process which contains the thread.
189 // |thread_koid| is the koid of the thread to register.
190 // |out_ref| points to where the registered thread reference should be returned.
191 //
192 // This function is thread-safe.
193 void trace_context_register_thread(
194 trace_context_t* context,
195 zx_koid_t process_koid, zx_koid_t thread_koid,
196 trace_thread_ref_t* out_ref);
197
198 // Registers a thread and returns its thread ref.
199 // Helper for |trace_context_register_thread()|.
trace_context_make_registered_thread(trace_context_t * context,zx_koid_t process_koid,zx_koid_t thread_koid)200 static inline trace_thread_ref_t trace_context_make_registered_thread(
201 trace_context_t* context,
202 zx_koid_t process_koid, zx_koid_t thread_koid) {
203 trace_thread_ref_t ref;
204 trace_context_register_thread(context, process_koid, thread_koid, &ref);
205 return ref;
206 }
207
208 // Allocate space for a blob and write its header.
209 // Returns a pointer to the "raw" contents of the blob,
210 // which must be filled in by the caller.
211 // Returns |nullptr| if there is no space in the buffer for |blob_size| bytes,
212 // or if |blob_size| is larger than TRACE_MAX_BLOB_SIZE.
213 // |context| must be a valid trace context reference.
214 // |type| is the blob type.
215 // |name_ref| is the name of the blob.
216 // |blob_size| is the size of the binary data to write.
217 // The caller is required to fill in the blob after we return.
218 // There is no need to zero out any padding, that has already been done.
219 void* trace_context_begin_write_blob_record(
220 trace_context_t* context,
221 trace_blob_type_t type,
222 const trace_string_ref_t* name_ref,
223 size_t blob_size);
224
225 // Write a blob of binary data into the trace buffer.
226 // Discards the record if it cannot be written.
227 // |context| must be a valid trace context reference.
228 // |type| is the blob type.
229 // |name_ref| is the name of the blob.
230 // |blob| is the binary data to write.
231 // |blob_size| is the size of the binary data to write.
232 void trace_context_write_blob_record(
233 trace_context_t* context,
234 trace_blob_type_t type,
235 const trace_string_ref_t* name_ref,
236 const void* blob, size_t blob_size);
237
238 // Writes a kernel object record for the object reference by the specified handle
239 // into the trace buffer. Discards the record if it cannot be written.
240 //
241 // Collects the necessary information by querying the object's type and properties.
242 //
243 // |context| must be a valid trace context reference.
244 // |handle| is the handle of the object being described.
245 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
246 //
247 // This function is thread-safe.
248 void trace_context_write_kernel_object_record_for_handle(
249 trace_context_t* context,
250 zx_handle_t handle,
251 const trace_arg_t* args, size_t num_args);
252
253 // Writes a kernel object record for the specified process into the trace buffer.
254 // Discards the record if it cannot be written.
255 //
256 // |context| must be a valid trace context reference.
257 // |process_koid| is the koid of the process being described.
258 // |process_name_ref| is the name of the process.
259 //
260 // This function is thread-safe.
261 void trace_context_write_process_info_record(
262 trace_context_t* context,
263 zx_koid_t process_koid,
264 const trace_string_ref_t* process_name_ref);
265
266 // Writes a kernel object record for the specified thread into the trace buffer.
267 // Discards the record if it cannot be written.
268 //
269 // |context| must be a valid trace context reference.
270 // |process_koid| is the koid of the process which contains the thread.
271 // |thread_koid| is the koid of the thread being described.
272 // |thread_name_ref| is the name of the thread.
273 //
274 // This function is thread-safe.
275 void trace_context_write_thread_info_record(
276 trace_context_t* context,
277 zx_koid_t process_koid, zx_koid_t thread_koid,
278 const trace_string_ref_t* thread_name_ref);
279
280 // Writes a context switch record into the trace buffer.
281 // Discards the record if it cannot be written.
282 //
283 // |context| must be a valid trace context reference.
284 // |event_time| is the time of the event, in ticks.
285 // |cpu_number| is the CPU upon which the context switch occurred.
286 // |outgoing_thread_state| is the state of the thread which was descheduled from the CPU.
287 // |outgoing_thread_ref| is the thread which was descheduled from the CPU.
288 // |incoming_thread_ref| is the thread which was scheduled on the CPU.
289 //
290 // This function is thread-safe.
291 void trace_context_write_context_switch_record(
292 trace_context_t* context,
293 trace_ticks_t event_time,
294 trace_cpu_number_t cpu_number,
295 trace_thread_state_t outgoing_thread_state,
296 const trace_thread_ref_t* outgoing_thread_ref,
297 const trace_thread_ref_t* incoming_thread_ref,
298 trace_thread_priority_t outgoing_thread_priority,
299 trace_thread_priority_t incoming_thread_priority);
300
301 // Writes a log record into the trace buffer.
302 // Discards the record if it cannot be written.
303 //
304 // |context| must be a valid trace context reference.
305 // |event_time| is the time of the event, in ticks.
306 // |thread_ref| is the thread which wrote the log message.
307 // |log_message| is the content of the log message.
308 // |log_message_length| is the length of the log message.
309 //
310 // This function is thread-safe.
311 void trace_context_write_log_record(
312 trace_context_t* context,
313 trace_ticks_t event_time,
314 const trace_thread_ref_t* thread_ref,
315 const char* log_message,
316 size_t log_message_length);
317
318 // Writes an instant event record with arguments into the trace buffer.
319 // Discards the record if it cannot be written.
320 //
321 // |context| must be a valid trace context reference.
322 // |event_time| is the time of the event, in ticks.
323 // |thread_ref| is the thread on which the event occurred.
324 // |category_ref| is the category of the event.
325 // |name_ref| is the name of the event.
326 // |scope| is the scope to which the instant event applies (thread, process, global).
327 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
328 //
329 // This function is thread-safe.
330 void trace_context_write_instant_event_record(
331 trace_context_t* context,
332 trace_ticks_t event_time,
333 const trace_thread_ref_t* thread_ref,
334 const trace_string_ref_t* category_ref,
335 const trace_string_ref_t* name_ref,
336 trace_scope_t scope,
337 const trace_arg_t* args, size_t num_args);
338
339 // Writes a counter event record with arguments into the trace buffer.
340 // Discards the record if it cannot be written.
341 //
342 // |context| must be a valid trace context reference.
343 // |event_time| is the time of the event, in ticks.
344 // |thread_ref| is the thread on which the event occurred.
345 // |category_ref| is the category of the event.
346 // |name_ref| is the name of the event.
347 // |counter_id| is the correlation id of the counter.
348 // Must be unique for a given process, category, and name combination.
349 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
350 //
351 // This function is thread-safe.
352 void trace_context_write_counter_event_record(
353 trace_context_t* context,
354 trace_ticks_t event_time,
355 const trace_thread_ref_t* thread_ref,
356 const trace_string_ref_t* category_ref,
357 const trace_string_ref_t* name_ref,
358 trace_counter_id_t counter_id,
359 const trace_arg_t* args, size_t num_args);
360
361 // Writes a duration begin event record and a duration end event record with
362 // arguments into the trace buffer.
363 // Discards the record if it cannot be written.
364 //
365 // |context| must be a valid trace context reference.
366 // |start_time| is the start time of the event, in ticks.
367 // |end_time| is the end time of the event, in ticks.
368 // |thread_ref| is the thread on which the event occurred.
369 // |category_ref| is the category of the event.
370 // |name_ref| is the name of the event.
371 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
372 //
373 // This function is thread-safe.
374 void trace_context_write_duration_event_record(
375 trace_context_t* context,
376 trace_ticks_t start_time,
377 trace_ticks_t end_time,
378 const trace_thread_ref_t* thread_ref,
379 const trace_string_ref_t* category_ref,
380 const trace_string_ref_t* name_ref,
381 const trace_arg_t* args, size_t num_args);
382
383 // Writes a duration begin event record with arguments into the trace buffer.
384 // Discards the record if it cannot be written.
385 //
386 // |context| must be a valid trace context reference.
387 // |event_time| is the start time of the event, in ticks.
388 // |thread_ref| is the thread on which the event occurred.
389 // |category_ref| is the category of the event.
390 // |name_ref| is the name of the event.
391 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
392 //
393 // This function is thread-safe.
394 void trace_context_write_duration_begin_event_record(
395 trace_context_t* context,
396 trace_ticks_t event_time,
397 const trace_thread_ref_t* thread_ref,
398 const trace_string_ref_t* category_ref,
399 const trace_string_ref_t* name_ref,
400 const trace_arg_t* args, size_t num_args);
401
402 // Writes a duration end event record with arguments into the trace buffer.
403 // Discards the record if it cannot be written.
404 //
405 // |context| must be a valid trace context reference.
406 // |event_time| is the end time of the event, in ticks.
407 // |thread_ref| is the thread on which the event occurred.
408 // |category_ref| is the category of the event.
409 // |name_ref| is the name of the event.
410 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
411 //
412 // This function is thread-safe.
413 void trace_context_write_duration_end_event_record(
414 trace_context_t* context,
415 trace_ticks_t event_time,
416 const trace_thread_ref_t* thread_ref,
417 const trace_string_ref_t* category_ref,
418 const trace_string_ref_t* name_ref,
419 const trace_arg_t* args, size_t num_args);
420
421 // Writes an asynchronous begin event record into the trace buffer.
422 // Discards the record if it cannot be written.
423 //
424 // |context| must be a valid trace context reference.
425 // |event_time| is the start time of the event, in ticks.
426 // |thread_ref| is the thread on which the event occurred.
427 // |category_ref| is the category of the event.
428 // |name_ref| is the name of the event.
429 // |async_id| is the correlation id of the asynchronous operation.
430 // Must be unique for a given process, category, and name combination.
431 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
432 //
433 // This function is thread-safe.
434 void trace_context_write_async_begin_event_record(
435 trace_context_t* context,
436 trace_ticks_t event_time,
437 const trace_thread_ref_t* thread_ref,
438 const trace_string_ref_t* category_ref,
439 const trace_string_ref_t* name_ref,
440 trace_async_id_t async_id,
441 const trace_arg_t* args, size_t num_args);
442
443 // Writes an asynchronous instant event record into the trace buffer.
444 // Discards the record if it cannot be written.
445 //
446 // |context| must be a valid trace context reference.
447 // |event_time| is the time of the event, in ticks.
448 // |thread_ref| is the thread on which the event occurred.
449 // |category_ref| is the category of the event.
450 // |name_ref| is the name of the event.
451 // |async_id| is the correlation id of the asynchronous operation.
452 // Must be unique for a given process, category, and name combination.
453 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
454 //
455 // This function is thread-safe.
456 void trace_context_write_async_instant_event_record(
457 trace_context_t* context,
458 trace_ticks_t event_time,
459 const trace_thread_ref_t* thread_ref,
460 const trace_string_ref_t* category_ref,
461 const trace_string_ref_t* name_ref,
462 trace_async_id_t async_id,
463 const trace_arg_t* args, size_t num_args);
464
465 // Writes an asynchronous end event record into the trace buffer.
466 // Discards the record if it cannot be written.
467 //
468 // |context| must be a valid trace context reference.
469 // |event_time| is the end time of the event, in ticks.
470 // |thread_ref| is the thread on which the event occurred.
471 // |category_ref| is the category of the event.
472 // |name_ref| is the name of the event.
473 // |async_id| is the correlation id of the asynchronous operation.
474 // Must be unique for a given process, category, and name combination.
475 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
476 //
477 // This function is thread-safe.
478 void trace_context_write_async_end_event_record(
479 trace_context_t* context,
480 trace_ticks_t event_time,
481 const trace_thread_ref_t* thread_ref,
482 const trace_string_ref_t* category_ref,
483 const trace_string_ref_t* name_ref,
484 trace_async_id_t async_id,
485 const trace_arg_t* args, size_t num_args);
486
487 // Writes a flow begin event record into the trace buffer.
488 // Discards the record if it cannot be written.
489 //
490 // |context| must be a valid trace context reference.
491 // |event_time| is the start time of the event, in ticks.
492 // |thread_ref| is the thread on which the event occurred.
493 // |category_ref| is the category of the event.
494 // |name_ref| is the name of the event.
495 // |flow_id| is the correlation id of the flow.
496 // Must be unique for a given category and name combination.
497 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
498 //
499 // This function is thread-safe.
500 void trace_context_write_flow_begin_event_record(
501 trace_context_t* context,
502 trace_ticks_t event_time,
503 const trace_thread_ref_t* thread_ref,
504 const trace_string_ref_t* category_ref,
505 const trace_string_ref_t* name_ref,
506 trace_flow_id_t flow_id,
507 const trace_arg_t* args, size_t num_args);
508
509 // Writes a flow step event record into the trace buffer.
510 // Discards the record if it cannot be written.
511 //
512 // |context| must be a valid trace context reference.
513 // |event_time| is the time of the event, in ticks.
514 // |thread_ref| is the thread on which the event occurred.
515 // |category_ref| is the category of the event.
516 // |name_ref| is the name of the event.
517 // |flow_id| is the correlation id of the flow.
518 // Must be unique for a given category and name combination.
519 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
520 //
521 // This function is thread-safe.
522 void trace_context_write_flow_step_event_record(
523 trace_context_t* context,
524 trace_ticks_t event_time,
525 const trace_thread_ref_t* thread_ref,
526 const trace_string_ref_t* category_ref,
527 const trace_string_ref_t* name_ref,
528 trace_flow_id_t flow_id,
529 const trace_arg_t* args, size_t num_args);
530
531 // Writes a flow end event record into the trace buffer.
532 // Discards the record if it cannot be written.
533 //
534 // |context| must be a valid trace context reference.
535 // |event_time| is the end time of the event, in ticks.
536 // |thread_ref| is the thread on which the event occurred.
537 // |category_ref| is the category of the event.
538 // |name_ref| is the name of the event.
539 // |flow_id| is the correlation id of the flow.
540 // Must be unique for a given category and name combination.
541 // |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
542 //
543 // This function is thread-safe.
544 void trace_context_write_flow_end_event_record(
545 trace_context_t* context,
546 trace_ticks_t event_time,
547 const trace_thread_ref_t* thread_ref,
548 const trace_string_ref_t* category_ref,
549 const trace_string_ref_t* name_ref,
550 trace_flow_id_t flow_id,
551 const trace_arg_t* args, size_t num_args);
552
553 // Writes an initialization record into the trace buffer.
554 // Discards the record if it cannot be written.
555 //
556 // |context| must be a valid trace context reference.
557 // |ticks_per_second| is the number of |trace_ticks_t| per second used in the trace.
558 //
559 // This function is thread-safe.
560 void trace_context_write_initialization_record(
561 trace_context_t* context,
562 zx_ticks_t ticks_per_second);
563
564 // Writes a string record into the trace buffer.
565 // Discards the record if it cannot be written.
566 //
567 // |context| must be a valid trace context reference.
568 // |index| is the index of the string, between |TRACE_ENCODED_STRING_REF_MIN_INDEX|
569 // and |TRACE_ENCODED_STRING_REF_MAX_INDEX| inclusive.
570 // |string| is the content of the string.
571 // |length| is the length of the string; the string will be truncated if it is longer
572 // than |TRACE_ENCODED_STRING_REF_MAX_LENGTH|.
573 //
574 // This function is thread-safe.
575 void trace_context_write_string_record(
576 trace_context_t* context,
577 trace_string_index_t index, const char* string, size_t length);
578
579 // Writes a thread record into the trace buffer.
580 // Discards the record if it cannot be written.
581 //
582 // |context| must be a valid trace context reference.
583 // |index| is the index of the thread, between |TRACE_ENCODED_THREAD_REF_MIN_INDEX|
584 // and |TRACE_ENCODED_THREAD_REF_MAX_INDEX| inclusive.
585 // |process_koid| is the koid of the process which contains the thread.
586 // |thread_koid| is the koid of the thread being described.
587 //
588 // This function is thread-safe.
589 void trace_context_write_thread_record(
590 trace_context_t* context,
591 trace_thread_index_t index,
592 zx_koid_t process_koid,
593 zx_koid_t thread_koid);
594
595 // Allocates space for a record in the trace buffer.
596 //
597 // |context| must be a valid trace context reference.
598 // |num_bytes| must be a multiple of 8 bytes.
599 //
600 // Returns a pointer to the allocated space within the trace buffer with
601 // 8 byte alignment, or NULL if the trace buffer is full or if |num_bytes|
602 // exceeds |TRACE_ENCODED_RECORD_MAX_LENGTH|.
603 //
604 // This function is thread-safe, fail-fast, and lock-free.
605 void* trace_context_alloc_record(trace_context_t* context, size_t num_bytes);
606
607 __END_CDECLS
608