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