#include <os/trace.h>

os/trace.h Kernel.framework

includes: Availability.h, os/base.h, sys/types.h, Kernel/stdint.h, Kernel/stdbool.h, Kernel/stdarg.h
14 macros · 6 functions · 1 variable · 1 typedef

variable__dso_handle

extern void *__dso_handle

function_os_trace_verify_printf

__attribute__((format(printf, 1, 2)))
OS_ALWAYS_INLINE 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_CALL

Use a new layout in Mac OS 10.12+ and iOS 10.0+
#define OS_TRACE_CALL(_l, _m, _t, ...) __extension__({
    uint8_t buf[1024];
    _os_trace_verify_printf(_l, ##__VA_ARGS__);
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, ##__VA_ARGS__);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, NULL);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_1

#define _os_trace_with_payload_1(_l, _m, _t, _payload) __extension__({
    _os_trace_verify_printf(_l);
    _os_trace_internal(&__dso_handle, _t, _m, NULL, 0, _payload);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_2

#define _os_trace_with_payload_2(_l, _m, _t, _1, _payload) __extension__({
    _os_trace_verify_printf(_l, _1);
    uint8_t buf[1024];
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, _1);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, _payload);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_3

#define _os_trace_with_payload_3(_l, _m, _t, _1, _2, _payload) __extension__({
    _os_trace_verify_printf(_l, _1, _2);
    uint8_t buf[1024];
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, _1, _2);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, _payload);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_4

#define _os_trace_with_payload_4(_l, _m, _t, _1, _2, _3, _payload) __extension__({
    _os_trace_verify_printf(_l, _1, _2, _3);
    uint8_t buf[1024];
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, _1, _2, _3);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, _payload);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_5

#define _os_trace_with_payload_5(_l, _m, _t, _1, _2, _3, _4, _payload) __extension__({
    _os_trace_verify_printf(_l, _1, _2, _3, _4);
    uint8_t buf[1024];
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, _1, _2, _3, _4);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, _payload);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_6

#define _os_trace_with_payload_6(_l, _m, _t, _1, _2, _3, _4, _5, _payload) __extension__({
    _os_trace_verify_printf(_l, _1, _2, _3, _4, _5);
    uint8_t buf[1024];
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, _1, _2, _3, _4, _5);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, _payload);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_7

#define _os_trace_with_payload_7(_l, _m, _t, _1, _2, _3, _4, _5, _6, _payload) __extension__({
    _os_trace_verify_printf(_l, _1, _2, _3, _4, _5, _6);
    uint8_t buf[1024];
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, _1, _2, _3, _4, _5, _6);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, _payload);
    __asm__(""); /* avoid tailcall */
})

macro_os_trace_with_payload_8

#define _os_trace_with_payload_8(_l, _m, _t, _1, _2, _3, _4, _5, _6, _7, _payload) __extension__({
    _os_trace_verify_printf(_l, _1, _2, _3, _4, _5, _6, _7);
    uint8_t buf[1024];
    size_t buf_size = _os_trace_encode(buf, sizeof(buf), _m, _1, _2, _3, _4, _5, _6, _7);
    _os_trace_internal(&__dso_handle, _t, _m, buf, buf_size, _payload);
    __asm__(""); /* avoid tailcall */
})

typedefos_trace_payload_t

@typedef os_trace_payload_t A block that populates an xpc_object_t of type XPC_TYPE_DICTIONARY to represent complex data. 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)(xpc_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. os_trace("network event: %ld, last seen: %ld, avg: %g", event_id, last_seen, avg);
#define os_trace(format, ...) __extension__({
    _Static_assert(__builtin_constant_p(format), "format must be a constant string");
    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;
   OS_TRACE_CALL(format, _m, OS_TRACE_TYPE_RELEASE, ##__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. os_trace_info("network interface status %ld", status);
#define os_trace_info(format, ...) __extension__({
    _Static_assert(__builtin_constant_p(format), "format must be a constant string");
    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;
   OS_TRACE_CALL(format, _m, OS_TRACE_TYPE_INFO, ##__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. os_trace_debug("network interface status %ld", status);
#define os_trace_debug(format, ...) __extension__({
    _Static_assert(__builtin_constant_p(format), "format must be a constant string");
    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;
   OS_TRACE_CALL(format, _m, OS_TRACE_TYPE_DEBUG, ##__VA_ARGS__);
})

functionos_trace_info_enabled

__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0)
OS_EXPORT OS_NOTHROW OS_WARN_RESULT bool os_trace_info_enabled(void)
@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. if (os_trace_info_enabled()) { os_trace_info("value = %d, average = %d", [[dict objectForKey: @"myKey"] intValue], (int) [self getAverage: dict]); } @result Returns true if development mode is enabled.

functionos_trace_debug_enabled

__OSX_AVAILABLE(10.10) __IOS_AVAILABLE(8.0) __WATCHOS_AVAILABLE(1.0) __TVOS_AVAILABLE(9.0)
OS_EXPORT OS_NOTHROW OS_WARN_RESULT bool os_trace_debug_enabled(void)
@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. if (os_trace_debug_enabled()) { os_trace_debug("value = %d, average = %d", [[dict objectForKey: @"myKey"] intValue], (int) [self getAverage: dict]); } @result Returns true if debug mode 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. os_trace_error("socket %d connection timeout %ld", fd, secs);
#define os_trace_error(format, ...) __extension__({
    _Static_assert(__builtin_constant_p(format), "format must be a constant string");
    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;
   OS_TRACE_CALL(format, _m, OS_TRACE_TYPE_ERROR, ##__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. os_trace_fault("failed to lookup uid %d - aborting", uid);
#define os_trace_fault(format, ...) __extension__({
    _Static_assert(__builtin_constant_p(format), "format must be a constant string");
    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;
    OS_TRACE_CALL(format, _m, OS_TRACE_TYPE_FAULT, ##__VA_ARGS__);
})

function_os_trace_encode

__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0)
OS_EXPORT OS_NOTHROW size_t _os_trace_encode(
	uint8_t *buf,
	size_t buf_size,
	const char *format,
	...
)
TODO: change this once we have compiler support

function_os_trace_internal

__OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0)
OS_EXPORT OS_NOTHROW void _os_trace_internal(
	void *dso,
	uint8_t type,
	const char *format,
	const uint8_t *buf,
	size_t buf_size,
	os_trace_payload_t payload
)
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu libkern/os/trace.h
Implementation entry point of the os_trace macros. Submits one trace event to the logging system: dso identifies the caller's image, type is the trace/log type, format is the constant format string (stored in the __TEXT segment), buf/buf_size carry the packed argument values encoded by the macros, and payload optionally supplies a block delivering a richer payload to diagnostic tools. Not intended to be called directly; use the os_trace family. Implemented in the logging subsystem, not in the xnu sources.

function_os_trace_with_buffer

__OSX_AVAILABLE(10.10) __IOS_AVAILABLE(8.0) __WATCHOS_AVAILABLE(1.0) __TVOS_AVAILABLE(9.0)
OS_EXPORT OS_NOTHROW 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
)
@function _os_trace_with_buffer @abstract Internal function to support pre-encoded buffer.