#include <os/trace.h>
os/trace.h
typedefos_trace_payload_object_t
typedef xpc_object_t os_trace_payload_object_t
function_os_trace_verify_printf
OS_ALWAYS_INLINE __attribute__((format(os_trace, 1, 2))) static inline void _os_trace_verify_printf( const char *msg, ... )
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu libkern/os/trace.h
Empty inline placeholder with a printf format attribute, called by the os_trace macros so the compiler type-checks the trace format string against its arguments. The call is optimized away; it exists solely for compile-time format verification.
macroOS_TRACE_UNINITIALIZED
#define OS_TRACE_UNINITIALIZED __attribute__((uninitialized))
macroOS_TRACE_CALL
#define OS_TRACE_CALL(_t, _p, _f, ...) __extension__({
if (os_trace_type_enabled(_t)) {
_os_trace_verify_printf(_f, ##__VA_ARGS__);
OS_LOG_STRING(TRACE, __f, _f);
uint32_t __size = (uint32_t)__builtin_os_log_format_buffer_size(_f, ##__VA_ARGS__);
OS_TRACE_UNINITIALIZED uint8_t _buf[__size];
__builtin_os_log_format(_buf, _f, ##__VA_ARGS__);
uint32_t tz = 0;
OS_TRACE_UNINITIALIZED uint8_t tb[__size];
uint8_t *buff = _buf;
uint8_t *p = ++buff;
uint8_t count = *p++;
uint8_t trailer[count + 1];
trailer[count] = count;
for (uint8_t ii = 0; ii < count; ii++) {
uint8_t desc = *p++;
uint8_t size = *p++;
uint8_t *value = p;
p += size;
if ((desc >> 4) || (desc & 0x1)) {
size = 0;
}
if (size) {
memcpy(&tb[tz], value, size);
tz += size;
}
trailer[ii] = size;
}
memcpy(&tb[tz], trailer, sizeof(trailer));
tz += sizeof(trailer);
_os_trace_with_buffer(&__dso_handle, __f, _t, tb, tz, _p);
}
})macro_os_trace_with_payload_1
macros to re-order arguments so we can call log function
#define _os_trace_with_payload_1(_t, _f, _p) OS_TRACE_CALL(_t, _p, _f)
macro_os_trace_with_payload_2
#define _os_trace_with_payload_2(_t, _f, _1, _p) OS_TRACE_CALL(_t, _p, _f, _1)
macro_os_trace_with_payload_3
#define _os_trace_with_payload_3(_t, _f, _1, _2, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2)
macro_os_trace_with_payload_4
#define _os_trace_with_payload_4(_t, _f, _1, _2, _3, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3)
macro_os_trace_with_payload_5
#define _os_trace_with_payload_5(_t, _f, _1, _2, _3, _4, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4)
macro_os_trace_with_payload_6
#define _os_trace_with_payload_6(_t, _f, _1, _2, _3, _4, _5, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4, _5)
macro_os_trace_with_payload_7
#define _os_trace_with_payload_7(_t, _f, _1, _2, _3, _4, _5, _6, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4, _5, _6)
macro_os_trace_with_payload_8
#define _os_trace_with_payload_8(_t, _f, _1, _2, _3, _4, _5, _6, _7, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4, _5, _6, _7)
macro_os_trace_call_n
#define _os_trace_call_n(_t, _f, ...) OS_TRACE_CALL(_t, NULL, _f, ##__VA_ARGS__)
macroOS_TRACE_TYPE_RELEASE
@define OS_TRACE_TYPE_RELEASE
Trace messages to be captured on a typical user install. These should be
limited to things which improve diagnosis of a failure/crash/hang. Trace
buffers are generally smaller on a production system.
#define OS_TRACE_TYPE_RELEASE (1u << 0)
macroOS_TRACE_TYPE_DEBUG
@define OS_TRACE_TYPE_DEBUG
Trace messages to be captured while debugger or other development tool is
attached to the originator.
#define OS_TRACE_TYPE_DEBUG (1u << 1)
macroOS_TRACE_TYPE_INFO
@define OS_TRACE_TYPE_INFO
Trace messages that are captured when a debugger is attached, system or
Application mode has been increased to include additional information.
#define OS_TRACE_TYPE_INFO (1u << 2)
macroOS_TRACE_TYPE_ERROR
@define OS_TRACE_TYPE_ERROR
Trace the message as an error and force a collection as a failure may be
imminent.
#define OS_TRACE_TYPE_ERROR ((1u << 6) | (1u << 0))
macroOS_TRACE_TYPE_FAULT
@define OS_TRACE_TYPE_FAULT
Trace the message as a fatal error which forces a collection and a diagnostic
to be initiated.
#define OS_TRACE_TYPE_FAULT ((1u << 7) | (1u << 6) | (1u << 0))
typedefos_trace_payload_t
@typedef os_trace_payload_t
@abstract A block that populates an xpc_object_t of type XPC_TYPE_DICTIONARY to
represent complex data.
@discussion This block will only be invoked under conditions where tools have attached to
the process. The payload can be used to send arbitrary data via the trace
call. Tools may use the data to validate state for integration tests or
provide other introspection services. No assumptions are made about the
format or structure of the data.
typedef void (^os_trace_payload_t)(os_trace_payload_object_t xdict)
macroos_trace
@function os_trace
@abstract Always inserts a trace message into a buffer pool for later decoding.
@discussion Trace message that will be recorded on a typical user install. These should
be limited to things which help diagnose a failure during postmortem
analysis. Trace buffers are generally smaller on a production system.
@param format
A printf-style format string to generate a human-readable log message when
the trace line is decoded. Only scalar types are supported, attempts
to pass arbitrary strings will store a pointer that is unresolvable and
will generate an error during decode.
<code>
os_trace("network event: %ld, last seen: %ld, avg: %g",
event_id, last_seen, avg);
</code>
#define os_trace(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_RELEASE, NULL, format, ##__VA_ARGS__)
macroos_trace_info
@function os_trace_info
@abstract Optionally inserts a trace message containing additional information into a
buffer pool for later decoding.
@discussion Trace messages that will be captured when additional information is needed
and are not captured by default. They will only be captured if the
system/process/activity mode has been increased or if a Development tool has
been attached to the process.
@param format
A printf-style format string that represents a human-readable message when
the trace line is decoded. Only scalar types are supported, attempts
to pass arbitrary strings will store a pointer that is unresolvable and
will generate an error during decode.
<code>
os_trace_info("network interface status %ld", status);
</code>
#define os_trace_info(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_INFO, NULL, format, ##__VA_ARGS__)
macroos_trace_debug
@function os_trace_debug
@abstract Insert debug trace message into a buffer pool for later decoding.
@discussion Debug trace message to be recorded while debugger or other development tool
is attached to the originator. This is transported interprocess to help
diagnose the entire call chain including external helpers.
@param format
A printf-style format string that represents a human-readable message when
the trace line is decoded. Only scalar types are supported, attempts
to pass arbitrary strings will store a pointer that is unresolvable and
will generate an error during decode.
<code>
os_trace_debug("network interface status %ld", status);
</code>
#define os_trace_debug(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_DEBUG, NULL, format, ##__VA_ARGS__)
functionos_trace_info_enabled
API_DEPRECATED_WITH_REPLACEMENT("os_log_info_enabled", macos(10.12,10.13), ios(10.0,11.0), watchos(3.0,4.0), tvos(10.0,11.0)) OS_EXPORT OS_NOTHROW OS_WARN_RESULT bool os_trace_info_enabled( void )
deprecated
@function os_trace_info_enabled
@abstract Avoid unnecessary work for a trace point by checking if additional
information is enabled.
@discussion Avoid unnecessary work for a trace point by checking if additional
information is enabled. Generally trace points should not involve expensive
operations, but some circumstances warrant it. Use this function to avoid
doing the work unless debug level trace messages are requested.
<code>
if (os_trace_info_enabled()) {
os_trace_info("value = %d, average = %d",
[[dict objectForKey: @"myKey"] intValue],
(int)[self getAverage:dict]);
}
</code>
@result Returns true if info types are enabled.
functionos_trace_debug_enabled
API_DEPRECATED_WITH_REPLACEMENT("os_log_debug_enabled", macos(10.10,10.13), ios(8.0,11.0), watchos(2.0,4.0), tvos(8.0,11.0)) OS_EXPORT OS_NOTHROW OS_WARN_RESULT bool os_trace_debug_enabled( void )
deprecated
@function os_trace_debug_enabled
@abstract Avoid unnecessary work for a trace point by checking if debug level is
enabled.
@discussion Avoid unnecessary work for a trace point by checking if debug level is
enabled. Generally trace points should not involve expensive operations, but
some circumstances warrant it. Use this function to avoid doing the work
unless debug level trace messages are requested.
<code>
if (os_trace_debug_enabled()) {
os_trace_debug("value = %d, average = %d",
[[dict objectForKey: @"myKey"] intValue],
(int)[self getAverage:dict]);
}
</code>
@result Returns true if debug mode is enabled.
functionos_trace_type_enabled
API_DEPRECATED_WITH_REPLACEMENT("os_log_type_enabled", macos(10.10,10.13), ios(8.0,11.0), watchos(2.0,4.0), tvos(8.0,11.0)) OS_NOTHROW OS_WARN_RESULT OS_ALWAYS_INLINE static inline bool os_trace_type_enabled( uint8_t type )
deprecated
@function os_trace_type_enabled
@abstract Avoid unnecessary work for a trace point by checking a specific type
@discussion Avoid unnecessary work for a trace point by checking a specific type
@result Returns true if type is enabled.
macroos_trace_error
@function os_trace_error
@abstract Trace the message as an error and force a collection of the trace buffer as
a failure may be imminent.
@discussion Trace the message as an error and force a collection of the trace buffer as
a failure may be imminent.
@param format
A printf-style format string to generate a human-readable log message when
the trace line is decoded. Only scalar types are supported, attempts to pass
arbitrary strings will store a pointer that is unresolvable and will generate
an error during decode.
<code>
os_trace_error("socket %d connection timeout %ld", fd, secs);
</code>
#define os_trace_error(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_ERROR, NULL, format, ##__VA_ARGS__)
macroos_trace_fault
@function os_trace_fault
@abstract Trace the message as a fault which forces a collection of the trace buffer
and diagnostic of the activity.
@discussion Trace the message as a fault which forces a collection of the trace buffer
and diagnostic of the activity.
@param format
A printf-style format string to generate a human-readable log message when
the trace line is decoded. Only scalar types are supported, attempts
to pass arbitrary strings will store a pointer that is unresolvable and
will generate an error during decode.
<code>
os_trace_fault("failed to lookup uid %d - aborting", uid);
</code>
#define os_trace_fault(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_FAULT, NULL, format, ##__VA_ARGS__)
macroos_trace_with_payload
@function os_trace_with_payload
@abstract Add a trace entry containing the provided values and call the block if
appropriate.
@discussion Will insert a trace entry into a limited ring buffer for an activity or
process. Trace points are for recording interesting data that would improve
diagnosis of unexpected crashes, failures and hangs. The block will only be
called under the required conditions.
@param trace_msg
A printf-style format string to generate a human-readable log message when
the trace line is decoded. Only scalar types are supported. Attempts
to pass arbitrary strings will store a pointer that is unresolvable and
will generate an error during decode.
The final parameter must be a block of type os_trace_payload_t.
<code>
os_trace_with_payload("network event %ld", event, ^(xpc_object_t xdict) {
// validate the network interface and address where what was expected
xpc_dictionary_set_string(xdict, "network", ifp->ifa_name);
xpc_dictionary_set_string(xdict, "ip_address", _get_address(ifp));
});
</code>
#define os_trace_with_payload(format, ...) OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))( OS_TRACE_TYPE_RELEASE, format, ##__VA_ARGS__)
macroos_trace_info_with_payload
#define os_trace_info_with_payload(format, ...) OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))( OS_TRACE_TYPE_INFO, format, ##__VA_ARGS__)
macroos_trace_debug_with_payload
#define os_trace_debug_with_payload(format, ...) OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))( OS_TRACE_TYPE_DEBUG, format, ##__VA_ARGS__)
macroos_trace_error_with_payload
#define os_trace_error_with_payload(format, ...) OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))( OS_TRACE_TYPE_ERROR, format, ##__VA_ARGS__)
macroos_trace_fault_with_payload
#define os_trace_fault_with_payload(format, ...) OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))( OS_TRACE_TYPE_FAULT, format, ##__VA_ARGS__)
function_os_trace_with_buffer
API_DEPRECATED("use one of the following calls instead: os_log_info, os_log_debug, os_log_error, os_log_fault", macos(10.10,10.13), ios(8.0,11.0), watchos(2.0,4.0), tvos(8.0,11.0)) OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED void _os_trace_with_buffer( void *dso, const char *message, uint8_t type, const void *buffer, size_t buffer_size, os_trace_payload_t payload )
deprecated
@function _os_trace_with_buffer
@abstract Internal function to support pre-encoded buffer.