Google is committed to advancing racial equity for Black communities. See how.

Tracing: C and C++ macros

You can use these C and C++ macros to record tracing data after you have set your component as a tracing provider. For more information, see Adding tracing in your code.

These macros are defined in //zircon/system/ulib/trace/include/lib/trace/internal/event_common.h.

Encoding macros

When you want to record a value with tracing macros, it is important that you properly encode each value. Use the respective macro based on the data type that you want to record.

Macro Description
TA_NULL

Optional for C++

A NULL value.

This macro does not take any arguments. You can use it as TA_NULL().

In C++, you can alternatively use nullptr.

TA_BOOL

Optional for C++

A boolean value.

TA_INT32

Optional for C++

A signed 32-bit integer value.

TA_UINT32

Optional for C++

An unsigned 32-bit integer value.

TA_INT64

Optional for C++

A signed 64-bit integer value.

TA_UINT64

Optional for C++

An unsigned 32-bit integer value.

TA_DOUBLE

Optional for C++

A double precision floating point value.

TA_CHAR_ARRAY

Required for C++

A character array with a length which is copied rather than cached.

This macro takes two arguments. The first argument is a pointer to the character array. The second argument is the length of the array.

TA_STRING

Optional for C++

A NULL terminated dynamic string which is copied rather than cached.

TA_STRING_LITERAL

Required for C++

A NULL terminated dynamic string which is cached.

TA_POINTER

Optional for C++

A pointer value which records the memory address and not the target.

TA_KOID

Required for C++

A kernel object ID. For more information, see Zircon kernel objects .

C++ notes

In C++, when you use a literal constant, type inference needs a hint in order to get the size, signedness, and type right.

For example, is the value 77 a signed 32-bit integer? An unsigned 32-bit integer? Or maybe even a 64-bit integer of some kind?

Type inference in the tracing macros works according to the standard C++ rules:

  • 77 is a signed 32-bit integer, TA_INT32
  • 77U is an unsigned 32-bit integer, TA_UINT32
  • 77L is a signed 64-bit integer, TA_INT64
  • 77LU is an unsigned 64-bit integer, TA_UINT64

This also means that floating point needs to be explicitly noted if it's an integer value.

For example:

  • 77 is a TA_INT32.
  • 77. is a TA_DOUBLE.

If you are using constants, you should consider retaining the encoding macros if you are expressing the values directly, or you should use the appropriate const type. The following examples all do the same thing, but show the use of a well defined type, a type macro, and a discouraged example.

Defined type

const int32_t my_id = 77;                       // well defined type
TRACE_INSTANT("category", "name", "int", my_id);

Type macro

#define MY_ID   (TA_INT32(77))                  // uses the typing macro
TRACE_INSTANT("category", "name", "int", MY_ID);

Discouraged

TRACE_INSTANT("category", "name", "int", 77);   // discouraged

TRACE_ENABLED

 Returns true if tracing is enabled.

 Usage:

     if (TRACE_ENABLED()) {
         // do something possibly expensive only when tracing is enabled
     }

TRACE_CATEGORY_ENABLED

 Returns true if tracing of the specified category has been enabled (which
 implies that |TRACE_ENABLED()| is also true).

 |category_literal| must be a null-terminated static string constant.

 Usage:

     if (TRACE_CATEGORY_ENABLED("category")) {
         // do something possibly expensive only when tracing this category
     }

TRACE_NONCE

 Returns a new unique 64-bit unsigned integer (within this process).
 Each invocation returns a different non-zero value.
 Useful for generating identifiers for async and flow events.

 Usage:

     trace_async_id_t async_id = TRACE_NONCE();
     TRACE_ASYNC_BEGIN("category", "name", async_id);
     // a little while later...
     TRACE_ASYNC_END("category", "name", async_id);

TRACE_INSTANT

 Writes an instant event representing a single moment in time (a probe).

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the moment with additional information.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |scope| is |TRACE_SCOPE_THREAD|, |TRACE_SCOPE_PROCESS|, or |TRACE_SCOPE_GLOBAL|.
 |args| is the list of argument key/value pairs.

 Usage:

     TRACE_INSTANT("category", "name", TRACE_SCOPE_PROCESS, "x", TA_INT32(42));

TRACE_COUNTER

 Writes a counter event with the specified id.

 The arguments to this event are numeric samples are typically represented by
 the visualizer as a stacked area chart.  The id serves to distinguish multiple
 instances of counters which share the same category and name within the
 same process.

 1 to 15 numeric arguments can be associated with the event, each of which is
 interpreted as a distinct time series.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |counter_id| is the correlation id of the counter.
              Must be unique for a given process, category, and name combination.
 |args| is the list of argument key/value pairs.

 Usage:

     trace_counter_id_t counter_id = 555;
     TRACE_COUNTER("category", "name", counter_id, "x", TA_INT32(42), "y", TA_DOUBLE(2.0))

TRACE_DURATION

 Writes a duration event which ends when the current scope exits.

 Durations describe work which is happening synchronously on one thread.
 They can be nested to represent a control flow stack.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the duration with additional information.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |args| is the list of argument key/value pairs.

 Usage:

     void function(int arg) {
         TRACE_DURATION("category", "name", "arg", TA_INT32(arg));
         // do something useful here
     }

TRACE_DURATION_BEGIN

 Writes a duration begin event only.
 This event must be matched by a duration end event with the same category and name.

 Durations describe work which is happening synchronously on one thread.
 They can be nested to represent a control flow stack.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the duration with additional information.  The arguments provided
 to matching duration begin and duration end events are combined together in
 the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |args| is the list of argument key/value pairs.

 Usage:

     TRACE_DURATION_BEGIN("category", "name", "x", TA_INT32(42));

TRACE_DURATION_END

 Writes a duration end event only.

 Durations describe work which is happening synchronously on one thread.
 They can be nested to represent a control flow stack.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the duration with additional information.  The arguments provided
 to matching duration begin and duration end events are combined together in
 the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |args| is the list of argument key/value pairs.

 Usage:

     TRACE_DURATION_END("category", "name", "x", TA_INT32(42));

TRACE_ASYNC_BEGIN

 Writes an asynchronous begin event with the specified id.
 This event may be followed by async instant events and must be matched by
 an async end event with the same category, name, and id.

 Asynchronous events describe work which is happening asynchronously and which
 may span multiple threads.  Asynchronous events do not nest.  The id serves
 to correlate the progress of distinct asynchronous operations which share
 the same category and name within the same process.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the asynchronous operation with additional information.  The
 arguments provided to matching async begin, async instant, and async end
 events are combined together in the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |async_id| is the correlation id of the asynchronous operation.
            Must be unique for a given process, category, and name combination.
 |args| is the list of argument key/value pairs.

 Usage:

     trace_async_id_t async_id = 555;
     TRACE_ASYNC_BEGIN("category", "name", async_id, "x", TA_INT32(42));

TRACE_ASYNC_INSTANT

 Writes an asynchronous instant event with the specified id.

 Asynchronous events describe work which is happening asynchronously and which
 may span multiple threads.  Asynchronous events do not nest.  The id serves
 to correlate the progress of distinct asynchronous operations which share
 the same category and name within the same process.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the asynchronous operation with additional information.  The
 arguments provided to matching async begin, async instant, and async end
 events are combined together in the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |async_id| is the correlation id of the asynchronous operation.
            Must be unique for a given process, category, and name combination.
 |args| is the list of argument key/value pairs.

 Usage:

     trace_async_id_t async_id = 555;
     TRACE_ASYNC_INSTANT("category", "name", async_id, "x", TA_INT32(42));

TRACE_ASYNC_END

 Writes an asynchronous end event with the specified id.

 Asynchronous events describe work which is happening asynchronously and which
 may span multiple threads.  Asynchronous events do not nest.  The id serves
 to correlate the progress of distinct asynchronous operations which share
 the same category and name within the same process.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the asynchronous operation with additional information.  The
 arguments provided to matching async begin, async instant, and async end
 events are combined together in the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |async_id| is the correlation id of the asynchronous operation.
            Must be unique for a given process, category, and name combination.
 |args| is the list of argument key/value pairs.

 Usage:

     trace_async_id_t async_id = 555;
     TRACE_ASYNC_END("category", "name", async_id, "x", TA_INT32(42));

TRACE_FLOW_BEGIN

 Writes a flow begin event with the specified id.
 This event may be followed by flow steps events and must be matched by
 a flow end event with the same category, name, and id.

 Flow events describe control flow handoffs between threads or across processes.
 They are typically represented as arrows in a visualizer.  Flow arrows are
 from the end of the duration event which encloses the beginning of the flow
 to the beginning of the duration event which encloses the next step or the
 end of the flow.  The id serves to correlate flows which share the same
 category and name across processes.

 This event must be enclosed in a duration event which represents where
 the flow handoff occurs.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the flow with additional information.  The arguments provided
 to matching flow begin, flow step, and flow end events are combined together
 in the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |flow_id| is the correlation id of the flow.
           Must be unique for a given category and name combination.
 |args| is the list of argument key/value pairs.

 Usage:

     trace_flow_id_t flow_id = 555;
     TRACE_FLOW_BEGIN("category", "name", flow_id, "x", TA_INT32(42));

TRACE_FLOW_STEP

 Writes a flow step event with the specified id.

 Flow events describe control flow handoffs between threads or across processes.
 They are typically represented as arrows in a visualizer.  Flow arrows are
 from the end of the duration event which encloses the beginning of the flow
 to the beginning of the duration event which encloses the next step or the
 end of the flow.  The id serves to correlate flows which share the same
 category and name across processes.

 This event must be enclosed in a duration event which represents where
 the flow handoff occurs.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the flow with additional information.  The arguments provided
 to matching flow begin, flow step, and flow end events are combined together
 in the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |flow_id| is the correlation id of the flow.
           Must be unique for a given category and name combination.
 |args| is the list of argument key/value pairs.

 Usage:

     trace_flow_id_t flow_id = 555;
     TRACE_FLOW_STEP("category", "name", flow_id, "x", TA_INT32(42));

TRACE_FLOW_END

 Writes a flow end event with the specified id.

 Flow events describe control flow handoffs between threads or across processes.
 They are typically represented as arrows in a visualizer.  Flow arrows are
 from the end of the duration event which encloses the beginning of the flow
 to the beginning of the duration event which encloses the next step or the
 end of the flow.  The id serves to correlate flows which share the same
 category and name across processes.

 This event must be enclosed in a duration event which represents where
 the flow handoff occurs.

 0 to 15 arguments can be associated with the event, each of which is used
 to annotate the flow with additional information.  The arguments provided
 to matching flow begin, flow step, and flow end events are combined together
 in the trace; it is not necessary to repeat them.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |flow_id| is the correlation id of the flow.
           Must be unique for a given category and name combination.
 |args| is the list of argument key/value pairs.

 Usage:

     trace_flow_id_t id = 555;
     TRACE_FLOW_END("category", "name", flow_id, "x", TA_INT32(42));

TRACE_BLOB_EVENT

 Writes a large blob record with the given blob data and metadata.
 Here metadata includes timestamp, thread and process information, and arguments,
 which is what most event records contain.

 Blobs which exceed |TRACE_ENCODED_RECORD_MAX_TOTAL_LENGTH| will be silently
 ignored, as will blobs which cannot fit within the remaining space in the
 trace buffer.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |blob| is a pointer to the data.
 |blob_size| is the size, in bytes, of the data.

TRACE_BLOB_ATTACHMENT

 Writes a large blob record with the given blob data, with only a
 category and name associated with the blob. This will not contain much
 additional metadata. This means timestamp, thread and process information,
 and arguments are not included with the record.

 Blobs which exceed |TRACE_ENCODED_RECORD_MAX_TOTAL_LENGTH| will be silently
 ignored, as will blobs which cannot fit within the remaining space in the
 trace buffer.

 |category_literal| and |name_literal| must be null-terminated static string constants.
 |blob| is a pointer to the data.
 |blob_size| is the size, in bytes, of the data.

TRACE_KERNEL_OBJECT

 Writes a description of a kernel object indicated by |handle|,
 including its koid, name, and the supplied arguments.

 0 to 15 arguments can be associated with the record, each of which is used
 to annotate the handle with additional information.

 |handle| is the handle of the object being described.
 |args| is the list of argument key/value pairs.

 Usage:

     zx_handle_t handle = ...;
     TRACE_KERNEL_OBJECT(handle, "description", TA_STRING("some object"));