#include <kern/kcdata.h>
kern/kcdata.h
THE KCDATA MANIFESTO
Kcdata is a self-describing data serialization format. It is meant to get
nested data structures out of xnu with minimum fuss, but also for that data
to be easy to parse. It is also meant to allow us to add new fields and
evolve the data format without breaking old parsers.
Kcdata is a permanent data format suitable for long-term storage including
in files. It is very important that we continue to be able to parse old
versions of kcdata-based formats. To this end, there are several
invariants you MUST MAINTAIN if you alter this file.
* None of the magic numbers should ever be a byteswap of themselves or
of any of the other magic numbers.
* Never remove any type.
* All kcdata structs must be packed, and must exclusively use fixed-size
types.
* Never change the definition of any type, except to add new fields to
the end.
* If you do add new fields to the end of a type, do not actually change
the definition of the old structure. Instead, define a new structure
with the new fields. See thread_snapshot_v3 as an example. This
provides source compatibility for old readers, and also documents where
the potential size cutoffs are.
* If you change libkdd, or kcdata.py run the unit tests under libkdd.
* If you add a type or extend an existing one, add a sample test to
libkdd/tests so future changes to libkdd will always parse your struct
correctly.
For example to add a field to this:
struct foobar {
uint32_t baz;
uint32_t quux;
} __attribute__ ((packed));
Define an evolved structure alongside it like this:
struct foobar_v2 {
uint32_t baz;
uint32_t quux;
///////// This is where the original structure's layout ended! sizeof(struct foobar) was 8 ////////
uint32_t frozzle;
} __attribute__ ((packed));
If you are parsing kcdata formats, you MUST
* Check the length field of each struct, including array elements. If the
struct is longer than you expect, you must ignore the extra data.
* Ignore any data types you do not understand.
Additionally, we want to be as forward compatible as we can. Meaning old
tools should still be able to use new data whenever possible. To this end,
you should:
* Try not to add new versions of types that supplant old ones. Instead
extend the length of existing types or add supplemental types.
* Try not to remove information from existing kcdata formats, unless
removal was explicitly asked for. For example it is fine to add a
stackshot flag to remove unwanted information, but you should not
remove it from the default stackshot if the new flag is absent.
* (TBD) If you do break old readers by removing information or
supplanting old structs, then increase the major version number.
The following is a description of the kcdata format.
The format for data is setup in a generic format as follows
Layout of data structure:
| 8 - bytes |
| type = MAGIC | LENGTH |
| 0 |
| type | size |
| flags |
| data |
|___________data____________|
| type | size |
| flags |
|___________data____________|
| type = END | size=0 |
| 0 |
The type field describes what kind of data is passed. For example type = TASK_CRASHINFO_UUID means the following data is a uuid.
These types need to be defined in task_corpse.h for easy consumption by userspace inspection tools.
Some range of types is reserved for special types like ints, longs etc. A cool new functionality made possible with this
extensible data format is that kernel can decide to put more information as required without requiring user space tools to
re-compile to be compatible. The case of rusage struct versions could be introduced without breaking existing tools.
Feature description: Generic data with description
-------------------
Further more generic data with description is very much possible now. For example
- kcdata_add_uint64_with_description(cdatainfo, 0x700, "NUM MACH PORTS");
- and more functions that allow adding description.
The userspace tools can then look at the description and print the data even if they are not compiled with knowledge of the field apriori.
Example data:
0000 57 f1 ad de 00 00 00 00 00 00 00 00 00 00 00 00 W...............
0010 01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 ........0.......
0020 50 49 44 00 00 00 00 00 00 00 00 00 00 00 00 00 PID.............
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040 9c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0050 01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 ........0.......
0060 50 41 52 45 4e 54 20 50 49 44 00 00 00 00 00 00 PARENT PID......
0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090 ed 58 91 f1
Feature description: Container markers for compound data
------------------
If a given kernel data type is complex and requires adding multiple optional fields inside a container
object for a consumer to understand arbitrary data, we package it using container markers.
For example, the stackshot code gathers information and describes the state of a given task with respect
to many subsystems. It includes data such as io stats, vm counters, process names/flags and syscall counts.
kcdata_add_container_marker(kcdata_p, KCDATA_TYPE_CONTAINER_BEGIN, STACKSHOT_KCCONTAINER_TASK, task_uniqueid);
// add multiple data, or add_<type>_with_description()s here
kcdata_add_container_marker(kcdata_p, KCDATA_TYPE_CONTAINER_END, STACKSHOT_KCCONTAINER_TASK, task_uniqueid);
Feature description: Custom Data formats on demand
--------------------
With the self describing nature of format, the kernel provider can describe a data type (uniquely identified by a number) and use
it in the buffer for sending data. The consumer can parse the type information and have knowledge of describing incoming data.
Following is an example of how we can describe a kernel specific struct sample_disk_io_stats in buffer.
struct sample_disk_io_stats {
uint64_t disk_reads_count;
uint64_t disk_reads_size;
uint64_t io_priority_count[4];
uint64_t io_priority_size;
} __attribute__ ((packed));
struct kcdata_subtype_descriptor disk_io_stats_def[] = {
{KCS_SUBTYPE_FLAGS_NONE, KC_ST_UINT64, 0 * sizeof(uint64_t), sizeof(uint64_t), "disk_reads_count"},
{KCS_SUBTYPE_FLAGS_NONE, KC_ST_UINT64, 1 * sizeof(uint64_t), sizeof(uint64_t), "disk_reads_size"},
{KCS_SUBTYPE_FLAGS_ARRAY, KC_ST_UINT64, 2 * sizeof(uint64_t), KCS_SUBTYPE_PACK_SIZE(4, sizeof(uint64_t)), "io_priority_count"},
{KCS_SUBTYPE_FLAGS_ARRAY, KC_ST_UINT64, (2 + 4) * sizeof(uint64_t), sizeof(uint64_t), "io_priority_size"},
};
Now you can add this custom type definition into the buffer as
kcdata_add_type_definition(kcdata_p, KCTYPE_SAMPLE_DISK_IO_STATS, "sample_disk_io_stats",
&disk_io_stats_def[0], sizeof(disk_io_stats_def)/sizeof(struct kcdata_subtype_descriptor));
Feature description: Compression
--------------------
In order to avoid keeping large amounts of memory reserved for a panic stackshot, kcdata has support
for compressing the buffer in a streaming fashion. New data pushed to the kcdata buffer will be
automatically compressed using an algorithm selected by the API user (currently, we only support
pass-through and zlib, in the future we plan to add WKDM support, see: 57913859).
To start using compression, call:
kcdata_init_compress(kcdata_p, hdr_tag, memcpy_f, comp_type);
where:
`kcdata_p` is the kcdata buffer that will be used
`hdr_tag` is the usual header tag denoting what type of kcdata buffer this will be
`memcpy_f` a memcpy(3) function to use to copy into the buffer, optional.
`compy_type` is the compression type, see KCDCT_ZLIB for an example.
Once compression is initialized:
(1) all self-describing APIs will automatically compress
(2) you can now use the following APIs to compress data into the buffer:
(None of the following will compress unless kcdata_init_compress() has been called)
- kcdata_push_data(kcdata_descriptor_t data, uint32_t type, uint32_t size, const void *input_data)
Pushes the buffer of kctype @type at[@input_data, @input_data + @size]
into the kcdata buffer @data, compressing if needed.
- kcdata_push_array(kcdata_descriptor_t data, uint32_t type_of_element,
uint32_t size_of_element, uint32_t count, const void *input_data)
Pushes the array found at @input_data, with element type @type_of_element, where
each element is of size @size_of_element and there are @count elements into the kcdata buffer
at @data.
- kcdata_compression_window_open/close(kcdata_descriptor_t data)
In case the data you are trying to push to the kcdata buffer @data is difficult to predict,
you can open a "compression window". Between an open and a close, no compression will be done.
Once you close the window, the underlying compression algorithm will compress the data into the buffer
and automatically rewind the current end marker of the kcdata buffer.
There is an ASCII art in kern_cdata.c to aid the reader in understanding
this.
- kcdata_finish_compression(kcdata_descriptor_t data)
Must be called at the end to flush any underlying buffers used by the compression algorithms.
This function will also add some statistics about the compression to the buffer which helps with
decompressing later.
macroKCDATA_FLAGS_STRUCT_PADDING_MASK
#define KCDATA_FLAGS_STRUCT_PADDING_MASK 0xf
macroKCDATA_FLAGS_STRUCT_HAS_PADDING
#define KCDATA_FLAGS_STRUCT_HAS_PADDING 0x80
macroKCDATA_ALIGNMENT_SIZE
kcdata aligns elements to 16 byte boundaries.
#define KCDATA_ALIGNMENT_SIZE 0x10
structkcdata_item
| uint32_t | type | |
| uint32_t | size | len(data) |
| uint64_t | flags | flags. For structures: padding = flags & 0xf has_padding = (flags & 0x80) >> 7 has_padding is needed to disambiguate cases such as thread_snapshot_v2 and thread_snapshot_v3. Their respective sizes are 0x68 and 0x70, and thread_snapshot_v2 was emitted by old kernels *before* we started recording padding. Since legacy thread_snapsht_v2 and modern thread_snapshot_v3 will both record 0 for the padding flags, we need some other bit which will be nonzero in the flags to disambiguate. This is why we hardcode a special case for STACKSHOT_KCTYPE_THREAD_SNAPSHOT into the iterator functions below. There is only a finite number of such hardcodings which will ever be needed. They can occur when: * We have a legacy structure that predates padding flags * which we want to extend without changing the kcdata type * by only so many bytes as would fit in the space that was previously unused padding. For containers: container_id = flags For arrays: element_count = flags & UINT32_MAX element_type = (flags >> 32) & UINT32_MAX |
| char[] | data | must be at the end |
typedefkcdata_item_t
typedef struct kcdata_item * kcdata_item_t
enumKCDATA_SUBTYPE_TYPES
| KC_ST_CHAR | 1 | |
| KC_ST_INT8 | 2 | |
| KC_ST_UINT8 | 3 | |
| KC_ST_INT16 | 4 | |
| KC_ST_UINT16 | 5 | |
| KC_ST_INT32 | 6 | |
| KC_ST_UINT32 | 7 | |
| KC_ST_INT64 | 8 | |
| KC_ST_UINT64 | 9 |
typedefkctype_subtype_t
typedef enum KCDATA_SUBTYPE_TYPES kctype_subtype_t
structkcdata_subtype_descriptor
A subtype description structure that defines
how a compound data is laid out in memory. This
provides on the fly definition of types and consumption
by the parser.
| uint8_t | kcs_flags | |
| uint8_t | kcs_elem_type | restricted to kctype_subtype_t |
| uint16_t | kcs_elem_offset | offset in struct where data is found |
| uint32_t | kcs_elem_size | size of element (or) packed state for array type |
| char[32] | kcs_name | max 31 bytes for name of field |
macroKCS_SUBTYPE_FLAGS_NONE
#define KCS_SUBTYPE_FLAGS_NONE 0x0
macroKCS_SUBTYPE_FLAGS_ARRAY
#define KCS_SUBTYPE_FLAGS_ARRAY 0x1
macroKCS_SUBTYPE_FLAGS_STRUCT
Force struct type even if only one element.
Normally a kcdata_type_definition is treated as a structure if it has
more than one subtype descriptor. Otherwise it is treated as a simple
type. For example libkdd will represent a simple integer 42 as simply
42, but it will represent a structure containing an integer 42 as
{"field_name": 42}..
If a kcdata_type_definition has only single subtype, then it will be
treated as a structure iff KCS_SUBTYPE_FLAGS_STRUCT is set. If it has
multiple subtypes, it will always be treated as a structure.
KCS_SUBTYPE_FLAGS_MERGE has the opposite effect. If this flag is used then
even if there are multiple elements, they will all be treated as individual
properties of the parent dictionary.
#define KCS_SUBTYPE_FLAGS_STRUCT 0x2
force struct type even if only one element
macroKCS_SUBTYPE_FLAGS_MERGE
#define KCS_SUBTYPE_FLAGS_MERGE 0x4
treat as multiple elements of parents instead of struct
typedefkcdata_subtype_descriptor_t
typedef struct kcdata_subtype_descriptor * kcdata_subtype_descriptor_t
macroKCS_SUBTYPE_PACK_SIZE
In case of array of basic c types in kctype_subtype_t,
size is packed in lower 16 bits and
count is packed in upper 16 bits of kcs_elem_size field.
#define KCS_SUBTYPE_PACK_SIZE(e_count, e_size) (((e_count)&0xffffu) << 16 | ((e_size)&0xffffu))
functionkcs_get_elem_size
static inline uint32_t kcs_get_elem_size(kcdata_subtype_descriptor_t d)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the total size in bytes of the field described by kcdata subtype descriptor d. For descriptors with KCS_SUBTYPE_FLAGS_ARRAY set, the element size (low 16 bits of kcs_elem_size) is multiplied by the element count (high 16 bits); otherwise kcs_elem_size is returned unchanged.
functionkcs_get_elem_count
static inline uint32_t kcs_get_elem_count(kcdata_subtype_descriptor_t d)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the number of elements in the field described by kcdata subtype descriptor d: the count packed into the upper 16 bits of kcs_elem_size when KCS_SUBTYPE_FLAGS_ARRAY is set, 1 otherwise.
functionkcs_set_elem_size
static inline int kcs_set_elem_size( kcdata_subtype_descriptor_t d, uint32_t size, uint32_t count )
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Sets the element size and count in kcdata subtype descriptor d. A count greater than 1 describes an array field and packs count and size into the upper and lower 16 bits of kcs_elem_size; returns -1 if either value exceeds 0xffff. Returns 0 on success.
structkcdata_type_definition
| uint32_t | kct_type_identifier | |
| uint32_t | kct_num_elements | |
| char[32] | kct_name | |
| struct kcdata_subtype_descriptor[] | kct_elements |
macroKCDATA_TYPE_INVALID
Types with description value.
these will have KCDATA_DESC_MAXLEN-1 length string description
and rest of kcdata_iter_size() - KCDATA_DESC_MAXLEN bytes as data
#define KCDATA_TYPE_INVALID 0x0u
macroKCDATA_TYPE_STRING_DESC
#define KCDATA_TYPE_STRING_DESC 0x1u
macroKCDATA_TYPE_UINT32_DESC
#define KCDATA_TYPE_UINT32_DESC 0x2u
macroKCDATA_TYPE_UINT64_DESC
#define KCDATA_TYPE_UINT64_DESC 0x3u
macroKCDATA_TYPE_INT32_DESC
#define KCDATA_TYPE_INT32_DESC 0x4u
macroKCDATA_TYPE_INT64_DESC
#define KCDATA_TYPE_INT64_DESC 0x5u
macroKCDATA_TYPE_BINDATA_DESC
#define KCDATA_TYPE_BINDATA_DESC 0x6u
macroKCDATA_TYPE_ARRAY
Compound type definitions
#define KCDATA_TYPE_ARRAY 0x11u
Array of data OBSOLETE DONT USE THIS
macroKCDATA_TYPE_TYPEDEFINTION
#define KCDATA_TYPE_TYPEDEFINTION 0x12u
Meta type that describes a type on the fly.
macroKCDATA_TYPE_CONTAINER_BEGIN
#define KCDATA_TYPE_CONTAINER_BEGIN 0x13u
Container type which has corresponding CONTAINER_END header. \
KCDATA_TYPE_CONTAINER_BEGIN has type in the data segment. \
Both headers have (uint64_t) ID for matching up nested data. \
macroKCDATA_TYPE_CONTAINER_END
#define KCDATA_TYPE_CONTAINER_END 0x14u
macroKCDATA_TYPE_LIBRARY_LOADINFO
Generic data types that are most commonly used
#define KCDATA_TYPE_LIBRARY_LOADINFO 0x30u
struct dyld_uuid_info_32
macroKCDATA_TYPE_LIBRARY_LOADINFO64
#define KCDATA_TYPE_LIBRARY_LOADINFO64 0x31u
struct dyld_uuid_info_64
macroKCDATA_TYPE_LIBRARY_AOTINFO
#define KCDATA_TYPE_LIBRARY_AOTINFO 0x39u
struct user64_dyld_aot_info
macroKCDATA_TYPE_BUFFER_END
#define KCDATA_TYPE_BUFFER_END 0xF19158EDu
macroKCDATA_BUFFER_BEGIN_CRASHINFO
#define KCDATA_BUFFER_BEGIN_CRASHINFO 0xDEADF157u
owner: corpses/task_corpse.h
macroKCDATA_BUFFER_BEGIN_STACKSHOT
type-range: 0x800 - 0x8ff
#define KCDATA_BUFFER_BEGIN_STACKSHOT 0x59a25807u
owner: sys/stackshot.h
macroKCDATA_BUFFER_BEGIN_COMPRESSED
type-range: 0x900 - 0x93f
#define KCDATA_BUFFER_BEGIN_COMPRESSED 0x434f4d50u
owner: sys/stackshot.h
macroKCDATA_BUFFER_BEGIN_DELTA_STACKSHOT
type-range: 0x900 - 0x93f
#define KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT 0xDE17A59Au
owner: sys/stackshot.h
macroKCDATA_BUFFER_BEGIN_BTINFO
type-range: 0x940 - 0x9ff
#define KCDATA_BUFFER_BEGIN_BTINFO 0x46414E47u
owner: kern/kern_exit.c
macroKCDATA_BUFFER_BEGIN_OS_REASON
type-range: 0xa01 - 0xaff
#define KCDATA_BUFFER_BEGIN_OS_REASON 0x53A20900u
owner: sys/reason.h
macroKCDATA_BUFFER_BEGIN_XNUPOST_CONFIG
type-range: 0x1000-0x103f
#define KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG 0x1e21c09fu
owner: osfmk/tests/kernel_tests.c
macroXNUPOST_KCTYPE_TESTCONFIG
next type range number available 0x1060
************** definitions for XNUPOST ********************
#define XNUPOST_KCTYPE_TESTCONFIG 0x1040
macroSTACKSHOT_IO_NUM_PRIORITIES
This value must always match IO_NUM_PRIORITIES defined in thread_info.h
#define STACKSHOT_IO_NUM_PRIORITIES 4
macroSTACKSHOT_MAX_THREAD_NAME_SIZE
This value must always match MAXTHREADNAMESIZE used in bsd
#define STACKSHOT_MAX_THREAD_NAME_SIZE 64
macroSTACKSHOT_KCTYPE_IOSTATS
NOTE: Please update kcdata/libkdd/kcdtypes.c if you make any changes
in STACKSHOT_KCTYPE_* types.
#define STACKSHOT_KCTYPE_IOSTATS 0x901u
macroSTACKSHOT_KCTYPE_GLOBAL_MEM_STATS
#define STACKSHOT_KCTYPE_GLOBAL_MEM_STATS 0x902u
struct mem_and_io_snapshot_v2
macroSTACKSHOT_KCCONTAINER_TASK
#define STACKSHOT_KCCONTAINER_TASK 0x903u
macroSTACKSHOT_KCCONTAINER_THREAD
#define STACKSHOT_KCCONTAINER_THREAD 0x904u
macroSTACKSHOT_KCTYPE_TASK_SNAPSHOT
#define STACKSHOT_KCTYPE_TASK_SNAPSHOT 0x905u
macroSTACKSHOT_KCTYPE_THREAD_SNAPSHOT
#define STACKSHOT_KCTYPE_THREAD_SNAPSHOT 0x906u
macroSTACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO
#define STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO 0x908u
macroSTACKSHOT_KCTYPE_KERN_STACKFRAME
#define STACKSHOT_KCTYPE_KERN_STACKFRAME 0x90Au
struct stack_snapshot_frame32
macroSTACKSHOT_KCTYPE_KERN_STACKFRAME64
#define STACKSHOT_KCTYPE_KERN_STACKFRAME64 0x90Bu
struct stack_snapshot_frame64
macroSTACKSHOT_KCTYPE_USER_STACKFRAME
#define STACKSHOT_KCTYPE_USER_STACKFRAME 0x90Cu
struct stack_snapshot_frame32
macroSTACKSHOT_KCTYPE_USER_STACKFRAME64
#define STACKSHOT_KCTYPE_USER_STACKFRAME64 0x90Du
struct stack_snapshot_frame64
macroSTACKSHOT_KCTYPE_OSVERSION
#define STACKSHOT_KCTYPE_OSVERSION 0x90Fu
os version string, same as running uname -a
macroSTACKSHOT_KCTYPE_KERN_PAGE_SIZE
#define STACKSHOT_KCTYPE_KERN_PAGE_SIZE 0x910u
kernel page size in uint32_t
macroSTACKSHOT_KCTYPE_JETSAM_LEVEL
#define STACKSHOT_KCTYPE_JETSAM_LEVEL 0x911u
jetsam level in uint32_t
macroSTACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP
#define STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP 0x912u
timestamp used for the delta stackshot
macroSTACKSHOT_KCTYPE_CPU_TIMES
#define STACKSHOT_KCTYPE_CPU_TIMES 0x919u
struct stackshot_cpu_times or stackshot_cpu_times_v2
macroSTACKSHOT_KCTYPE_STACKSHOT_DURATION
#define STACKSHOT_KCTYPE_STACKSHOT_DURATION 0x91au
struct stackshot_duration
macroSTACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS
#define STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS 0x91bu
struct stackshot_fault_stats
macroSTACKSHOT_KCTYPE_KERNELCACHE_LOADINFO
#define STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO 0x91cu
kernelcache UUID -- same as KCDATA_TYPE_LIBRARY_LOADINFO64
macroSTACKSHOT_KCTYPE_THREAD_WAITINFO
#define STACKSHOT_KCTYPE_THREAD_WAITINFO 0x91du
struct stackshot_thread_waitinfo
macroSTACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT
#define STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT 0x91eu
struct thread_group_snapshot{,_v2,_v3}
macroSTACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT
#define STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT 0x920u
struct jetsam_coalition_snapshot
macroSTACKSHOT_KCTYPE_THREAD_POLICY_VERSION
#define STACKSHOT_KCTYPE_THREAD_POLICY_VERSION 0x922u
THREAD_POLICY_INTERNAL_STRUCT_VERSION in uint32
macroSTACKSHOT_KCTYPE_INSTRS_CYCLES
#define STACKSHOT_KCTYPE_INSTRS_CYCLES 0x923u
struct instrs_cycles_snapshot_v2
macroSTACKSHOT_KCTYPE_USER_STACKTOP
#define STACKSHOT_KCTYPE_USER_STACKTOP 0x924u
struct stack_snapshot_stacktop
macroSTACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT
#define STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT 0x927u
same as KCDATA_TYPE_LIBRARY_LOADINFO64
macroSTACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL
#define STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL 0x928u
dispatch queue label
macroSTACKSHOT_KCTYPE_THREAD_TURNSTILEINFO
#define STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO 0x929u
macroSTACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE
#define STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE 0x92au
struct stackshot_cpu_architecture
macroSTACKSHOT_KCTYPE_LATENCY_INFO
#define STACKSHOT_KCTYPE_LATENCY_INFO 0x92bu
macroSTACKSHOT_KCTYPE_LATENCY_INFO_TASK
#define STACKSHOT_KCTYPE_LATENCY_INFO_TASK 0x92cu
struct stackshot_latency_task
macroSTACKSHOT_KCTYPE_LATENCY_INFO_THREAD
#define STACKSHOT_KCTYPE_LATENCY_INFO_THREAD 0x92du
struct stackshot_latency_thread
macroSTACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC
#define STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC 0x92eu
TEXT_EXEC load info -- same as KCDATA_TYPE_LIBRARY_LOADINFO64
macroSTACKSHOT_KCTYPE_AOTCACHE_LOADINFO
#define STACKSHOT_KCTYPE_AOTCACHE_LOADINFO 0x92fu
struct dyld_aot_cache_uuid_info
macroSTACKSHOT_KCTYPE_TRANSITIONING_TASK_SNAPSHOT
#define STACKSHOT_KCTYPE_TRANSITIONING_TASK_SNAPSHOT 0x930u
macroSTACKSHOT_KCCONTAINER_TRANSITIONING_TASK
#define STACKSHOT_KCCONTAINER_TRANSITIONING_TASK 0x931u
macroSTACKSHOT_KCTYPE_USER_ASYNC_START_INDEX
#define STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX 0x932u
uint32_t index in user_stack of beginning of async stack
macroSTACKSHOT_KCTYPE_USER_ASYNC_STACKLR64
#define STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64 0x933u
uint64_t async stack pointers
macroSTACKSHOT_KCCONTAINER_PORTLABEL
#define STACKSHOT_KCCONTAINER_PORTLABEL 0x934u
container for port label info
macroSTACKSHOT_KCTYPE_DYLD_COMPACTINFO
#define STACKSHOT_KCTYPE_DYLD_COMPACTINFO 0x937u
binary blob of dyld info (variable size)
macroSTACKSHOT_KCTYPE_SUSPENSION_INFO
#define STACKSHOT_KCTYPE_SUSPENSION_INFO 0x938u
struct stackshot_suspension_info
macroSTACKSHOT_KCTYPE_SUSPENSION_SOURCE
#define STACKSHOT_KCTYPE_SUSPENSION_SOURCE 0x939u
struct stackshot_suspension_source
macroSTACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT
#define STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT 0x940u
macroSTACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT
#define STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT 0x941u
thread_delta_snapshot_v*
macroSTACKSHOT_KCCONTAINER_SHAREDCACHE
#define STACKSHOT_KCCONTAINER_SHAREDCACHE 0x942u
container for shared cache info
macroSTACKSHOT_KCTYPE_SHAREDCACHE_INFO
#define STACKSHOT_KCTYPE_SHAREDCACHE_INFO 0x943u
macroSTACKSHOT_KCTYPE_SHAREDCACHE_AOTINFO
#define STACKSHOT_KCTYPE_SHAREDCACHE_AOTINFO 0x944u
struct dyld_aot_cache_uuid_info
macroSTACKSHOT_KCTYPE_SHAREDCACHE_ID
#define STACKSHOT_KCTYPE_SHAREDCACHE_ID 0x945u
uint32_t in task: if we aren't attached to Primary, which one
macroSTACKSHOT_KCTYPE_CODESIGNING_INFO
#define STACKSHOT_KCTYPE_CODESIGNING_INFO 0x946u
macroSTACKSHOT_KCTYPE_OS_BUILD_VERSION
#define STACKSHOT_KCTYPE_OS_BUILD_VERSION 0x947u
os build version string (ex: 20A123)
macroSTACKSHOT_KCTYPE_KERN_EXCLAVES_THREADINFO
#define STACKSHOT_KCTYPE_KERN_EXCLAVES_THREADINFO 0x948u
macroSTACKSHOT_KCCONTAINER_EXCLAVES
#define STACKSHOT_KCCONTAINER_EXCLAVES 0x949u
macroSTACKSHOT_KCCONTAINER_EXCLAVE_SCRESULT
#define STACKSHOT_KCCONTAINER_EXCLAVE_SCRESULT 0x94au
macroSTACKSHOT_KCTYPE_EXCLAVE_SCRESULT_INFO
#define STACKSHOT_KCTYPE_EXCLAVE_SCRESULT_INFO 0x94bu
macroSTACKSHOT_KCCONTAINER_EXCLAVE_IPCSTACKENTRY
#define STACKSHOT_KCCONTAINER_EXCLAVE_IPCSTACKENTRY 0x94cu
macroSTACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_INFO
#define STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_INFO 0x94du
macroSTACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_ECSTACK
#define STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_ECSTACK 0x94eu
macroSTACKSHOT_KCCONTAINER_EXCLAVE_ADDRESSSPACE
#define STACKSHOT_KCCONTAINER_EXCLAVE_ADDRESSSPACE 0x94fu
macroSTACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_INFO
#define STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_INFO 0x950u
macroSTACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_NAME
#define STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_NAME 0x951u
macroSTACKSHOT_KCCONTAINER_EXCLAVE_TEXTLAYOUT
#define STACKSHOT_KCCONTAINER_EXCLAVE_TEXTLAYOUT 0x952u
macroSTACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO
#define STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO 0x953u
macroSTACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS
#define STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS 0x954u
macroSTACKSHOT_KCTYPE_KERN_EXCLAVES_CRASH_THREADINFO
#define STACKSHOT_KCTYPE_KERN_EXCLAVES_CRASH_THREADINFO 0x955u
macroSTACKSHOT_KCTYPE_LATENCY_INFO_CPU
#define STACKSHOT_KCTYPE_LATENCY_INFO_CPU 0x956u
struct stackshot_latency_cpu
macroSTACKSHOT_KCTYPE_TASK_EXEC_META
#define STACKSHOT_KCTYPE_TASK_EXEC_META 0x957u
struct task_exec_meta
macroSTACKSHOT_KCTYPE_TASK_MEMORYSTATUS
#define STACKSHOT_KCTYPE_TASK_MEMORYSTATUS 0x958u
struct task_memorystatus_snapshot
macroSTACKSHOT_KCTYPE_LATENCY_INFO_BUFFER
#define STACKSHOT_KCTYPE_LATENCY_INFO_BUFFER 0x95au
struct stackshot_latency_buffer
macroSTACKSHOT_KCTYPE_VMRL_BLOCKING_RELS
#define STACKSHOT_KCTYPE_VMRL_BLOCKING_RELS 0x95bu
macroSTACKSHOT_KCTYPE_LOCK_STATE
#define STACKSHOT_KCTYPE_LOCK_STATE 0x95cu
struct stackshot_device_lock_state
structstack_snapshot_frame32
| uint32_t | lr | |
| uint32_t | sp |
structstack_snapshot_frame64
| uint64_t | lr | |
| uint64_t | sp |
structdyld_uuid_info_32
| uint32_t | imageLoadAddress | base address image is mapped at |
| uuid_t | imageUUID |
structdyld_uuid_info_64
| uint64_t | imageLoadAddress | XXX image slide |
| uuid_t | imageUUID |
structdyld_uuid_info_64_v2
N.B.: Newer kernels output dyld_shared_cache_loadinfo structures
instead of this, since the field names match their contents better.
| uint64_t | imageLoadAddress | XXX image slide |
| uuid_t | imageUUID | |
| uint64_t | imageSlidBaseAddress | end of version 1 of dyld_uuid_info_64. sizeof v1 was 24 slid base address or slid first mapping of image |
structdyld_aot_cache_uuid_info
| uint64_t | x86SlidBaseAddress | slid first mapping address of x86 shared cache |
| uuid_t | x86UUID | UUID of x86 shared cache |
| uint64_t | aotSlidBaseAddress | slide first mapping address of aot cache |
| uuid_t | aotUUID | UUID of aot shared cache |
structuser32_dyld_uuid_info
| uint32_t | imageLoadAddress | base address image is mapped into |
| uuid_t | imageUUID | UUID of image |
structuser64_dyld_uuid_info
| uint64_t | imageLoadAddress | base address image is mapped into |
| uuid_t | imageUUID | UUID of image |
structuser64_dyld_aot_info
| uint64_t | x86LoadAddress | |
| uint64_t | aotLoadAddress | |
| uint64_t | aotImageSize | |
| uint8_t[32] | aotImageKey |
enumtask_snapshot_flags
| kTaskRsrcFlagged | 4 | k{User,Kernel}64_p (values 0x1 and 0x2) are defined in generic_snapshot_flags In the EXC_RESOURCE danger zone? |
| kTerminatedSnapshot | 8 | |
| kPidSuspended | 16 | true for suspended task |
| kFrozen | 32 | true for hibernated task (along with pidsuspended) |
| kTaskDarwinBG | 64 | |
| kTaskExtDarwinBG | 128 | |
| kTaskVisVisible | 256 | |
| kTaskVisNonvisible | 512 | |
| kTaskIsForeground | 1024 | |
| kTaskIsBoosted | 2048 | |
| kTaskIsSuppressed | 4096 | |
| kTaskIsTimerThrottled | 8192 | deprecated |
| kTaskIsImpDonor | 16384 | |
| kTaskIsLiveImpDonor | 32768 | |
| kTaskIsDirty | 65536 | |
| kTaskWqExceededConstrainedThreadLimit | 131072 | |
| kTaskWqExceededTotalThreadLimit | 262144 | |
| kTaskWqFlagsAvailable | 524288 | |
| kTaskUUIDInfoFaultedIn | 1048576 | successfully faulted in some UUID info |
| kTaskUUIDInfoMissing | 2097152 | some UUID info was paged out |
| kTaskUUIDInfoTriedFault | 4194304 | tried to fault in UUID info |
| kTaskSharedRegionInfoUnavailable | 8388608 | shared region info unavailable |
| kTaskTALEngaged | 16777216 | |
| kTaskIsDirtyTracked | 67108864 | 0x2000000 unused |
| kTaskAllowIdleExit | 134217728 | |
| kTaskIsTranslated | 268435456 | |
| kTaskSharedRegionNone | 536870912 | task doesn't have a shared region |
| kTaskSharedRegionSystem | 1073741824 | task attached to region with kSharedCacheSystemPrimary set |
| kTaskSharedRegionOther | 2147483648 | task is attached to a different shared region |
| kTaskDyldCompactInfoNone | 4294967296 | |
| kTaskDyldCompactInfoTooBig | 8589934592 | |
| kTaskDyldCompactInfoFaultedIn | 17179869184 | |
| kTaskDyldCompactInfoMissing | 34359738368 | |
| kTaskDyldCompactInfoTriedFault | 68719476736 | |
| kTaskWqExceededCooperativeThreadLimit | 137438953472 | |
| kTaskWqExceededActiveConstrainedThreadLimit | 274877906944 | |
| kTaskRunawayMitigation | 549755813888 | |
| kTaskIsActive | 1099511627776 | |
| kTaskIsManaged | 2199023255552 | |
| kTaskHasAssertion | 4398046511104 |
Note: Add any new flags to kcdata.py (ts_ss_flags)
enumtask_transition_type
| kTaskIsTerminated | 1 | Past LPEXIT |
enumtask_exec_flags
See kcdata_private.h for more flag definitions
| kTaskExecTranslated | 1 | Task is running under translation (eg, Rosetta) |
| kTaskExecHardenedHeap | 2 | Task has the hardened heap security feature |
| kTaskExecReserved00 | 4 | |
| kTaskExecReserved01 | 8 | |
| kTaskExecReserved02 | 16 | |
| kTaskExecReserved03 | 32 |
structtask_exec_meta
metadata about a task that is fixed at spawn/exec time
| uint64_t | tem_flags | task_exec_flags |
enummte_info_cell_state_t
MTE info cell state, must match mte_cell_state_t
| MTE_INFO_STATE_DISABLED | 0 | |
| MTE_INFO_STATE_PINNED | 1 | |
| MTE_INFO_STATE_DEACTIVATING | 2 | |
| MTE_INFO_STATE_CLAIMED | 3 | |
| MTE_INFO_STATE_INACTIVE | 4 | |
| MTE_INFO_STATE_RECLAIMING | 5 | |
| MTE_INFO_STATE_ACTIVATING | 6 | |
| MTE_INFO_STATE_ACTIVE | 7 |
typedefmte_info_cell_state_t
typedef enum mte_info_cell_state_t mte_info_cell_state_t;
structmte_info_cell
MTE info cell data
| uint8_t | mic_state | |
| uint8_t | mic_tagged_count | Number of tagged pages in this tag storage page |
| uint8_t | mic_free_count | Number of free pages in this tag storage page |
| uint8_t | mic_wired_count | Number of wired pages in this tag storage page, regardless of tagging |
| uint8_t | mic_wired_tagged_count | Number of tagged pages wired that aren't used by kernel memory allocators |
| uint8_t | mic_kernel_wired_tagged_count | Number of tagged pages wired for use by the kernel memory allocators, kmem and zalloc |
enumthread_snapshot_flags
| kHasDispatchSerial | 4 | k{User,Kernel}64_p (values 0x1 and 0x2) are defined in generic_snapshot_flags |
| kStacksPCOnly | 8 | Stack traces have no frame pointers. |
| kThreadDarwinBG | 16 | Thread is darwinbg |
| kThreadIOPassive | 32 | Thread uses passive IO |
| kThreadSuspended | 64 | Thread is suspended |
| kThreadTruncatedBT | 128 | Unmapped pages caused truncated backtrace |
| kGlobalForcedIdle | 256 | Thread performs global forced idle |
| kThreadFaultedBT | 512 | Some thread stack pages were faulted in as part of BT |
| kThreadTriedFaultBT | 1024 | We tried to fault in thread stack pages as part of BT |
| kThreadOnCore | 2048 | Thread was on-core when we entered debugger context |
| kThreadIdleWorker | 4096 | Thread is an idle libpthread worker thread |
| kThreadMain | 8192 | Thread is the main thread |
| kThreadTruncKernBT | 16384 | Unmapped pages caused truncated kernel BT |
| kThreadTruncUserBT | 32768 | Unmapped pages caused truncated user BT |
| kThreadTruncUserAsyncBT | 65536 | Unmapped pages caused truncated user async BT |
Note: Add any new flags to kcdata.py (ths_ss_flags)
structmem_and_io_snapshot
| uint32_t | snapshot_magic | |
| uint32_t | free_pages | |
| uint32_t | active_pages | |
| uint32_t | inactive_pages | |
| uint32_t | purgeable_pages | |
| uint32_t | wired_pages | |
| uint32_t | speculative_pages | |
| uint32_t | throttled_pages | |
| uint32_t | filebacked_pages | |
| uint32_t | compressions | |
| uint32_t | decompressions | |
| uint32_t | compressor_size | |
| int32_t | busy_buffer_count | |
| uint32_t | pages_wanted | |
| uint32_t | pages_reclaimed | |
| uint8_t | pages_wanted_reclaimed_valid | did mach_vm_pressure_monitor succeed? |
structmem_and_io_snapshot_v2
| uint32_t | snapshot_magic | |
| uint32_t | free_pages | |
| uint32_t | active_pages | |
| uint32_t | inactive_pages | |
| uint32_t | purgeable_pages | |
| uint32_t | wired_pages | |
| uint32_t | speculative_pages | |
| uint32_t | throttled_pages | |
| uint32_t | filebacked_pages | |
| uint32_t | compressions | |
| uint32_t | decompressions | |
| uint32_t | compressor_size | |
| int32_t | busy_buffer_count | |
| uint32_t | pages_wanted | |
| uint32_t | pages_reclaimed | |
| uint8_t | pages_wanted_reclaimed_valid | did mach_vm_pressure_monitor succeed? |
| uint32_t | shared_region_pages | |
| uint32_t | compressed_pages | |
| uint32_t | swapped_pages |
structthread_snapshot_v2
| uint64_t | ths_thread_id | |
| uint64_t | ths_wait_event | |
| uint64_t | ths_continuation | |
| uint64_t | ths_total_syscalls | |
| uint64_t | ths_voucher_identifier | |
| uint64_t | ths_dqserialnum | |
| uint64_t | ths_user_time | |
| uint64_t | ths_sys_time | |
| uint64_t | ths_ss_flags | |
| uint64_t | ths_last_run_time | |
| uint64_t | ths_last_made_runnable_time | |
| uint32_t | ths_state | |
| uint32_t | ths_sched_flags | |
| int16_t | ths_base_priority | |
| int16_t | ths_sched_priority | |
| uint8_t | ths_eqos | |
| uint8_t | ths_rqos | |
| uint8_t | ths_rqos_override | |
| uint8_t | ths_io_tier |
structthread_snapshot_v3
| uint64_t | ths_thread_id | |
| uint64_t | ths_wait_event | |
| uint64_t | ths_continuation | |
| uint64_t | ths_total_syscalls | |
| uint64_t | ths_voucher_identifier | |
| uint64_t | ths_dqserialnum | |
| uint64_t | ths_user_time | |
| uint64_t | ths_sys_time | |
| uint64_t | ths_ss_flags | |
| uint64_t | ths_last_run_time | |
| uint64_t | ths_last_made_runnable_time | |
| uint32_t | ths_state | |
| uint32_t | ths_sched_flags | |
| int16_t | ths_base_priority | |
| int16_t | ths_sched_priority | |
| uint8_t | ths_eqos | |
| uint8_t | ths_rqos | |
| uint8_t | ths_rqos_override | |
| uint8_t | ths_io_tier | |
| uint64_t | ths_thread_t |
structthread_snapshot_v4
| uint64_t | ths_thread_id | |
| uint64_t | ths_wait_event | |
| uint64_t | ths_continuation | |
| uint64_t | ths_total_syscalls | |
| uint64_t | ths_voucher_identifier | |
| uint64_t | ths_dqserialnum | |
| uint64_t | ths_user_time | |
| uint64_t | ths_sys_time | |
| uint64_t | ths_ss_flags | |
| uint64_t | ths_last_run_time | |
| uint64_t | ths_last_made_runnable_time | |
| uint32_t | ths_state | |
| uint32_t | ths_sched_flags | |
| int16_t | ths_base_priority | |
| int16_t | ths_sched_priority | |
| uint8_t | ths_eqos | |
| uint8_t | ths_rqos | |
| uint8_t | ths_rqos_override | |
| uint8_t | ths_io_tier | |
| uint64_t | ths_thread_t | |
| uint64_t | ths_requested_policy | |
| uint64_t | ths_effective_policy |
structthread_group_snapshot
| uint64_t | tgs_id | |
| char[16] | tgs_name |
enumthread_group_flags
In general these flags mirror their THREAD_GROUP_FLAGS_ counterparts.
THREAD_GROUP_FLAGS_UI_APP was repurposed and THREAD_GROUP_FLAGS_APPLICATION
introduced to take its place. To remain compatible, kThreadGroupUIApp is
kept around and kThreadGroupUIApplication introduced.
| kThreadGroupEfficient | 1 | |
| kThreadGroupApplication | 2 | |
| kThreadGroupUIApp | 2 | |
| kThreadGroupCritical | 4 | |
| kThreadGroupBestEffort | 8 | |
| kThreadGroupUIApplication | 256 | |
| kThreadGroupManaged | 512 | |
| kThreadGroupStrictTimers | 1024 |
Note: Add any new flags to kcdata.py (tgs_flags)
structthread_group_snapshot_v2
| uint64_t | tgs_id | |
| char[16] | tgs_name | |
| uint64_t | tgs_flags |
structthread_group_snapshot_v3
| uint64_t | tgs_id | |
| char[16] | tgs_name | |
| uint64_t | tgs_flags | |
| char[16] | tgs_name_cont |
enumcoalition_flags
| kCoalitionTermRequested | 1 | |
| kCoalitionTerminated | 2 | |
| kCoalitionReaped | 4 | |
| kCoalitionPrivileged | 8 |
Note: Add any new flags to kcdata.py (jcs_flags)
structjetsam_coalition_snapshot
| uint64_t | jcs_id | |
| uint64_t | jcs_flags | |
| uint64_t | jcs_thread_group | |
| uint64_t | jcs_leader_task_uniqueid |
structinstrs_cycles_snapshot
| uint64_t | ics_instructions | |
| uint64_t | ics_cycles |
structinstrs_cycles_snapshot_v2
| uint64_t | ics_instructions | |
| uint64_t | ics_cycles | |
| uint64_t | ics_p_instructions | |
| uint64_t | ics_p_cycles |
structthread_delta_snapshot_v2
| uint64_t | tds_thread_id | |
| uint64_t | tds_voucher_identifier | |
| uint64_t | tds_ss_flags | |
| uint64_t | tds_last_made_runnable_time | |
| uint32_t | tds_state | |
| uint32_t | tds_sched_flags | |
| int16_t | tds_base_priority | |
| int16_t | tds_sched_priority | |
| uint8_t | tds_eqos | |
| uint8_t | tds_rqos | |
| uint8_t | tds_rqos_override | |
| uint8_t | tds_io_tier |
structthread_delta_snapshot_v3
| uint64_t | tds_thread_id | |
| uint64_t | tds_voucher_identifier | |
| uint64_t | tds_ss_flags | |
| uint64_t | tds_last_made_runnable_time | |
| uint32_t | tds_state | |
| uint32_t | tds_sched_flags | |
| int16_t | tds_base_priority | |
| int16_t | tds_sched_priority | |
| uint8_t | tds_eqos | |
| uint8_t | tds_rqos | |
| uint8_t | tds_rqos_override | |
| uint8_t | tds_io_tier | |
| uint64_t | tds_requested_policy | |
| uint64_t | tds_effective_policy |
structio_stats_snapshot
| uint64_t | ss_disk_reads_count | I/O Statistics XXX: These fields must be together. |
| uint64_t | ss_disk_reads_size | |
| uint64_t | ss_disk_writes_count | |
| uint64_t | ss_disk_writes_size | |
| uint64_t[4] | ss_io_priority_count | |
| uint64_t[4] | ss_io_priority_size | |
| uint64_t | ss_paging_count | |
| uint64_t | ss_paging_size | |
| uint64_t | ss_non_paging_count | |
| uint64_t | ss_non_paging_size | |
| uint64_t | ss_data_count | |
| uint64_t | ss_data_size | |
| uint64_t | ss_metadata_count | |
| uint64_t | ss_metadata_size |
structtask_snapshot_v2
| uint64_t | ts_unique_pid | |
| uint64_t | ts_ss_flags | |
| uint64_t | ts_user_time_in_terminated_threads | |
| uint64_t | ts_system_time_in_terminated_threads | |
| uint64_t | ts_p_start_sec | |
| uint64_t | ts_task_size | |
| uint64_t | ts_max_resident_size | |
| uint32_t | ts_suspend_count | |
| uint32_t | ts_faults | |
| uint32_t | ts_pageins | |
| uint32_t | ts_cow_faults | |
| uint32_t | ts_was_throttled | |
| uint32_t | ts_did_throttle | |
| uint32_t | ts_latency_qos | |
| int32_t | ts_pid | |
| char[32] | ts_p_comm |
structtask_snapshot_v3
| uint64_t | ts_unique_pid | |
| uint64_t | ts_ss_flags | |
| uint64_t | ts_user_time_in_terminated_threads | |
| uint64_t | ts_system_time_in_terminated_threads | |
| uint64_t | ts_p_start_sec | |
| uint64_t | ts_task_size | |
| uint64_t | ts_max_resident_size | |
| uint32_t | ts_suspend_count | |
| uint32_t | ts_faults | |
| uint32_t | ts_pageins | |
| uint32_t | ts_cow_faults | |
| uint32_t | ts_was_throttled | |
| uint32_t | ts_did_throttle | |
| uint32_t | ts_latency_qos | |
| int32_t | ts_pid | |
| char[32] | ts_p_comm | |
| uint32_t | ts_uid | |
| uint32_t | ts_gid |
structtransitioning_task_snapshot
| uint64_t | tts_unique_pid | |
| uint64_t | tts_ss_flags | |
| uint64_t | tts_transition_type | |
| int32_t | tts_pid | |
| char[32] | tts_p_comm |
structtask_delta_snapshot_v2
| uint64_t | tds_unique_pid | |
| uint64_t | tds_ss_flags | |
| uint64_t | tds_user_time_in_terminated_threads | |
| uint64_t | tds_system_time_in_terminated_threads | |
| uint64_t | tds_task_size | |
| uint64_t | tds_max_resident_size | |
| uint32_t | tds_suspend_count | |
| uint32_t | tds_faults | |
| uint32_t | tds_pageins | |
| uint32_t | tds_cow_faults | |
| uint32_t | tds_was_throttled | |
| uint32_t | tds_did_throttle | |
| uint32_t | tds_latency_qos |
structtask_memorystatus_snapshot
| int32_t | tms_current_memlimit | |
| int32_t | tms_effectivepriority | |
| int32_t | tms_requestedpriority | |
| int32_t | tms_assertionpriority |
macroKCDATA_INVALID_CS_TRUST_LEVEL
#define KCDATA_INVALID_CS_TRUST_LEVEL 0xffffffff
structstackshot_task_codesigning_info
| uint64_t | csflags | |
| uint32_t | cs_trust_level |
structstackshot_cpu_times
| uint64_t | user_usec | |
| uint64_t | system_usec |
structstackshot_cpu_times_v2
| uint64_t | user_usec | |
| uint64_t | system_usec | |
| uint64_t | runnable_usec |
structstackshot_duration
| uint64_t | stackshot_duration | |
| uint64_t | stackshot_duration_outer |
structstackshot_duration_v2
| uint64_t | stackshot_duration | |
| uint64_t | stackshot_duration_outer | |
| uint64_t | stackshot_duration_prior |
structstackshot_fault_stats
| uint32_t | sfs_pages_faulted_in | number of pages faulted in using KDP fault path |
| uint64_t | sfs_time_spent_faulting | MATUs spent faulting |
| uint64_t | sfs_system_max_fault_time | MATUs fault time limit per stackshot |
| uint8_t | sfs_stopped_faulting | we stopped decompressing because we hit the limit |
structstackshot_thread_waitinfo
| uint64_t | owner | The thread that owns the object |
| uint64_t | waiter | The thread that's waiting on the object |
| uint64_t | context | A context uniquely identifying the object |
| uint8_t | wait_type | The type of object that the thread is waiting on |
typedefthread_waitinfo_t
typedef struct stackshot_thread_waitinfo thread_waitinfo_t;
structstackshot_thread_waitinfo_v2
| uint64_t | owner | The thread that owns the object |
| uint64_t | waiter | The thread that's waiting on the object |
| uint64_t | context | A context uniquely identifying the object |
| uint8_t | wait_type | The type of object that the thread is waiting on |
| int16_t | portlabel_id | matches to a stackshot_portlabel, or NONE or MISSING |
| uint32_t | wait_flags | info about the wait |
typedefthread_waitinfo_v2_t
typedef struct stackshot_thread_waitinfo_v2 thread_waitinfo_v2_t;
macroSTACKSHOT_WAITINFO_FLAGS_SPECIALREPLY
#define STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY 0x1
We're waiting on a special reply port
macroSTACKSHOT_WAITINFO_FLAGS_BOOTSTRAP
#define STACKSHOT_WAITINFO_FLAGS_BOOTSTRAP 0x2
We're waiting on a bootstrap port
structstackshot_vmrl_blocking_relationship
| uint64_t | waiter_tid | |
| uint64_t | blocker_tid | |
| uint64_t | entry_hash | |
| uint32_t | flags |
typedefvmrl_blocking_relationship_t
typedef struct stackshot_vmrl_blocking_relationship vmrl_blocking_relationship_t;
macroSTACKSHOT_WAITER_VMRL_SHARED
#define STACKSHOT_WAITER_VMRL_SHARED 0x01
macroSTACKSHOT_BLOCKER_VMRL_SHARED
#define STACKSHOT_BLOCKER_VMRL_SHARED 0x02
macroSTACKSHOT_WAITER_VMRL_EXCLUSIVE
#define STACKSHOT_WAITER_VMRL_EXCLUSIVE 0x04
macroSTACKSHOT_BLOCKER_VMRL_EXCLUSIVE
#define STACKSHOT_BLOCKER_VMRL_EXCLUSIVE 0x08
macroSTACKSHOT_WAITER_VMRL_STREAMING
#define STACKSHOT_WAITER_VMRL_STREAMING 0x10
macroSTACKSHOT_BLOCKER_VMRL_STREAMING
#define STACKSHOT_BLOCKER_VMRL_STREAMING 0x20
macroSTACKSHOT_WAITER_VMRL_ATOMIC
#define STACKSHOT_WAITER_VMRL_ATOMIC 0x40
macroSTACKSHOT_BLOCKER_VMRL_ATOMIC
#define STACKSHOT_BLOCKER_VMRL_ATOMIC 0x80
structstackshot_thread_turnstileinfo
| uint64_t | waiter | The thread that's waiting on the object |
| uint64_t | turnstile_context | Associated data (either thread id, or workq addr) |
| uint8_t | turnstile_priority | |
| uint8_t | number_of_hops | |
| uint64_t | turnstile_flags | see below |
typedefthread_turnstileinfo_t
typedef struct stackshot_thread_turnstileinfo thread_turnstileinfo_t;
structstackshot_thread_turnstileinfo_v2
| uint64_t | waiter | The thread that's waiting on the object |
| uint64_t | turnstile_context | Associated data (either thread id, or workq addr) |
| uint8_t | turnstile_priority | |
| uint8_t | number_of_hops | |
| uint64_t | turnstile_flags | Note: Add any new flags to kcdata.py (turnstile_flags) |
| int16_t | portlabel_id | matches to a stackshot_portlabel, or NONE or MISSING |
typedefthread_turnstileinfo_v2_t
typedef struct stackshot_thread_turnstileinfo_v2 thread_turnstileinfo_v2_t;
macroSTACKSHOT_TURNSTILE_STATUS_UNKNOWN
#define STACKSHOT_TURNSTILE_STATUS_UNKNOWN 0x01
The final inheritor is unknown (bug?)
macroSTACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ
#define STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ 0x02
A waitq was found to be locked
macroSTACKSHOT_TURNSTILE_STATUS_WORKQUEUE
#define STACKSHOT_TURNSTILE_STATUS_WORKQUEUE 0x04
The final inheritor is a workqueue
macroSTACKSHOT_TURNSTILE_STATUS_THREAD
#define STACKSHOT_TURNSTILE_STATUS_THREAD 0x08
The final inheritor is a thread
macroSTACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK
#define STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK 0x10
blocked on task, dind't find thread
macroSTACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK
#define STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK 0x20
the ip_lock was held
macroSTACKSHOT_TURNSTILE_STATUS_SENDPORT
#define STACKSHOT_TURNSTILE_STATUS_SENDPORT 0x40
port_labelid was from a send port
macroSTACKSHOT_TURNSTILE_STATUS_RECEIVEPORT
#define STACKSHOT_TURNSTILE_STATUS_RECEIVEPORT 0x80
port_labelid was from a receive port
macroSTACKSHOT_TURNSTILE_STATUS_PORTFLAGS
#define STACKSHOT_TURNSTILE_STATUS_PORTFLAGS (STACKSHOT_TURNSTILE_STATUS_SENDPORT | STACKSHOT_TURNSTILE_STATUS_RECEIVEPORT)
macroSTACKSHOT_PORTLABELID_MISSING
#define STACKSHOT_PORTLABELID_MISSING (-1)
portlabel found, but stackshot ran out of space to track it
macroSTACKSHOT_WAITOWNER_KERNEL
#define STACKSHOT_WAITOWNER_KERNEL (UINT64_MAX - 1)
macroSTACKSHOT_WAITOWNER_PORT_LOCKED
#define STACKSHOT_WAITOWNER_PORT_LOCKED (UINT64_MAX - 2)
macroSTACKSHOT_WAITOWNER_PSET_LOCKED
#define STACKSHOT_WAITOWNER_PSET_LOCKED (UINT64_MAX - 3)
macroSTACKSHOT_WAITOWNER_INTRANSIT
#define STACKSHOT_WAITOWNER_INTRANSIT (UINT64_MAX - 4)
macroSTACKSHOT_WAITOWNER_MTXSPIN
#define STACKSHOT_WAITOWNER_MTXSPIN (UINT64_MAX - 5)
macroSTACKSHOT_WAITOWNER_THREQUESTED
#define STACKSHOT_WAITOWNER_THREQUESTED (UINT64_MAX - 6)
workloop waiting for a new worker thread
macroSTACKSHOT_WAITOWNER_SUSPENDED
#define STACKSHOT_WAITOWNER_SUSPENDED (UINT64_MAX - 7)
workloop is suspended
macroSTACKSHOT_PORTLABEL_READFAILED
#define STACKSHOT_PORTLABEL_READFAILED 0x1
could not read port information
macroSTACKSHOT_PORTLABEL_THROTTLED
#define STACKSHOT_PORTLABEL_THROTTLED 0x2
service port is marked as throttled
structportlabel_info
| int16_t | portlabel_id | kcdata-specific ID for this port label |
| uint16_t | portlabel_flags | STACKSHOT_PORTLABEL_* |
| uint8_t | portlabel_domain | launchd domain |
structstackshot_cpu_architecture
| int32_t | cputype | |
| int32_t | cpusubtype |
structstack_snapshot_stacktop
| uint64_t | sp | |
| uint8_t[8] | stack_contents |
structstackshot_latency_collection
only collected if STACKSHOT_COLLECTS_LATENCY_INFO is set to !0
| uint64_t | latency_version | |
| uint64_t | setup_latency | |
| uint64_t | total_task_iteration_latency | |
| uint64_t | total_terminated_task_iteration_latency |
structstackshot_latency_collection_v2
only collected if STACKSHOT_COLLECTS_LATENCY_INFO is set to !0
| uint64_t | latency_version | |
| uint64_t | setup_latency_mt | |
| uint64_t | total_task_iteration_latency_mt | |
| uint64_t | total_terminated_task_iteration_latency_mt | |
| uint64_t | task_queue_building_latency_mt | |
| uint64_t | terminated_task_queue_building_latency_mt | |
| uint64_t | cpu_wait_latency_mt | |
| int32_t | main_cpu_number | |
| int32_t | calling_cpu_number | |
| uint64_t | buffer_size | |
| uint64_t | buffer_used | |
| uint64_t | buffer_overhead | |
| uint64_t | buffer_count |
structstackshot_latency_cpu
only collected if STACKSHOT_COLLECTS_LATENCY_INFO is set to !0
| int32_t | cpu_number | |
| int32_t | cluster_type | |
| uint64_t | init_latency_mt | |
| uint64_t | workqueue_latency_mt | |
| uint64_t | total_latency_mt | |
| uint64_t | total_cycles | |
| uint64_t | total_instrs | |
| uint64_t | tasks_processed | |
| uint64_t | threads_processed | |
| uint64_t | faulting_time_mt | |
| uint64_t | total_buf | |
| uint64_t | intercluster_buf_used |
structstackshot_latency_buffer
only collected if STACKSHOT_COLLECTS_LATENCY_INFO is set to !0
| int32_t | cluster_type | |
| uint64_t | size | |
| uint64_t | used | |
| uint64_t | overhead |
structstackshot_latency_task
only collected if STACKSHOT_COLLECTS_LATENCY_INFO is set to !0
| uint64_t | task_uniqueid | |
| uint64_t | setup_latency | |
| uint64_t | task_thread_count_loop_latency | |
| uint64_t | task_thread_data_loop_latency | |
| uint64_t | cur_tsnap_latency | |
| uint64_t | pmap_latency | |
| uint64_t | bsd_proc_ids_latency | |
| uint64_t | misc_latency | |
| uint64_t | misc2_latency | |
| uint64_t | end_latency |
structstackshot_latency_thread
only collected if STACKSHOT_COLLECTS_LATENCY_INFO is set to !0
| uint64_t | thread_id | |
| uint64_t | cur_thsnap1_latency | |
| uint64_t | dispatch_serial_latency | |
| uint64_t | dispatch_label_latency | |
| uint64_t | cur_thsnap2_latency | |
| uint64_t | thread_name_latency | |
| uint64_t | sur_times_latency | |
| uint64_t | user_stack_latency | |
| uint64_t | kernel_stack_latency | |
| uint64_t | misc_latency |
structstackshot_suspension_info
| uint64_t | tss_last_start | mach_absolute_time of beginning of last suspension |
| uint64_t | tss_last_end | mach_absolute_time of end of last suspension |
| uint64_t | tss_count | number of times this task has been suspended |
| uint64_t | tss_duration | sum(mach_absolute_time) of time spend suspended |
structstackshot_suspension_source
| uint64_t | tss_time | mach_absolute_time of suspend |
| uint64_t | tss_tid | tid of suspending thread |
| int | tss_pid | pid of suspending task |
| char[65] | tss_procname | name of suspending task |
structstackshot_device_lock_state
| uint8_t | flags | interpret as a stackshot_device_lock_flags_t |
| uint8_t | passcode_status | interpret as a passcode_status_t |
| uint8_t | lock_state | interpret as a device_lock_state_t |
enumthread_exclaves_flags
| kExclaveRPCActive | 1 | Thread is handling RPC call in secure world |
| kExclaveUpcallActive | 2 | Thread has upcalled back into xnu while handling RPC |
| kExclaveSchedulerRequest | 4 | Thread is handling scheduler request |
structthread_exclaves_info
| uint64_t | tei_scid | |
| uint32_t | tei_thread_offset | |
| uint32_t | tei_flags |
structthread_crash_exclaves_info
| uint64_t | tcei_scid | |
| uint64_t | tcei_thread_id | Corresponding xnu thread id |
| uint32_t | tcei_flags |
enumexclave_scresult_flags
| kExclaveScresultHaveIPCStack | 1 |
structexclave_scresult_info
| uint64_t | esc_id | |
| uint64_t | esc_flags |
enumexclave_ipcstackentry_flags
| kExclaveIpcStackEntryHaveInvocationID | 1 | |
| kExclaveIpcStackEntryHaveStack | 2 |
structexclave_ipcstackentry_info
| uint64_t | eise_asid | ASID |
| uint64_t | eise_tnid | Thread numeric ID, may be UINT64_MAX if ommitted |
| uint64_t | eise_invocationid | Invocation ID, may be UINT64_MAX if ommitted |
| uint64_t | eise_flags |
typedefexclave_ecstackentry_addr_t
typedef uint64_t exclave_ecstackentry_addr_t
enumexclave_addressspace_flags
| kExclaveAddressSpaceHaveSlide | 1 | slide info provided |
structexclave_addressspace_info
| uint64_t | eas_id | ASID |
| uint64_t | eas_flags | |
| uint64_t | eas_layoutid | textLayout for this address space |
| uint64_t | eas_slide | slide to apply to textlayout, or UINT64_MAX if omitted |
| uint64_t | eas_asroot | ASRoot/TTBR0 value used as an identifier for the address space by cL4 |
enumexclave_textlayout_flags
| kExclaveTextLayoutLoadAddressesSynthetic | 1 | Load Addresses are synthetic |
| kExclaveTextLayoutLoadAddressesUnslid | 2 | Load Addresses are accurate and unslid |
| kExclaveTextLayoutHasSharedCache | 4 |
structexclave_textlayout_info_v1
| uint64_t | layout_id | |
| uint64_t | etl_flags |
structexclave_textlayout_info
| uint64_t | layout_id | |
| uint64_t | etl_flags | |
| uint32_t | sharedcache_index | index in SEGMENTs, or UINT32_MAX |
structexclave_textlayout_segment
| uuid_t | layoutSegment_uuid | |
| uint64_t | layoutSegment_loadAddress | Synthetic Load Address |
structexclave_textlayout_segment_v2
| uuid_t | layoutSegment_uuid | |
| uint64_t | layoutSegment_loadAddress | Synthetic Load Address |
| uint64_t | layoutSegment_rawLoadAddress | Raw Load Address when unslided |
structcrashinfo_proc_uniqidentifierinfo
| uint8_t[16] | p_uuid | UUID of the main executable |
| uint64_t | p_uniqueid | 64 bit unique identifier for process |
| uint64_t | p_puniqueid | unique identifier for process's parent |
| uint64_t | p_reserve2 | reserved for future use |
| uint64_t | p_reserve3 | reserved for future use |
| uint64_t | p_reserve4 | reserved for future use |
macroMAX_TRIAGE_STRING_LEN
#define MAX_TRIAGE_STRING_LEN (128)
structkernel_triage_info_v1
| char[128] | triage_string1 | |
| char[128] | triage_string2 | |
| char[128] | triage_string3 | |
| char[128] | triage_string4 | |
| char[128] | triage_string5 |
structcrashinfo_jit_address_range
| uint64_t | start_address | |
| uint64_t | end_address |
structcrashinfo_mb
| uint64_t | start_address | |
| uint64_t[64] | data |
structcrashinfo_task_security_config
| uint32_t | task_security_config | struct task_security_config |
structcrashinfo_voucher
| uint64_t | thread_id | |
| uint32_t | originator_pid | |
| uint32_t | proximate_pid |
macroMAX_CRASHINFO_SIGNING_ID_LEN
#define MAX_CRASHINFO_SIGNING_ID_LEN 64
macroMAX_CRASHINFO_TEAM_ID_LEN
#define MAX_CRASHINFO_TEAM_ID_LEN 32
macroMAX_CRASHINFO_SANDBOX_PROFILE_LEN
#define MAX_CRASHINFO_SANDBOX_PROFILE_LEN 32
macroTASK_CRASHINFO_BEGIN
#define TASK_CRASHINFO_BEGIN KCDATA_BUFFER_BEGIN_CRASHINFO
macroTASK_CRASHINFO_STRING_DESC
#define TASK_CRASHINFO_STRING_DESC KCDATA_TYPE_STRING_DESC
macroTASK_CRASHINFO_UINT32_DESC
#define TASK_CRASHINFO_UINT32_DESC KCDATA_TYPE_UINT32_DESC
macroTASK_CRASHINFO_UINT64_DESC
#define TASK_CRASHINFO_UINT64_DESC KCDATA_TYPE_UINT64_DESC
macroTASK_CRASHINFO_EXTMODINFO
#define TASK_CRASHINFO_EXTMODINFO 0x801
macroTASK_CRASHINFO_BSDINFOWITHUNIQID
#define TASK_CRASHINFO_BSDINFOWITHUNIQID 0x802
macroTASK_CRASHINFO_TASKDYLD_INFO
#define TASK_CRASHINFO_TASKDYLD_INFO 0x803
macroTASK_CRASHINFO_UUID
#define TASK_CRASHINFO_UUID 0x804
macroTASK_CRASHINFO_PID
#define TASK_CRASHINFO_PID 0x805
macroTASK_CRASHINFO_PPID
#define TASK_CRASHINFO_PPID 0x806
macroTASK_CRASHINFO_RUSAGE
#define TASK_CRASHINFO_RUSAGE 0x807
struct rusage DEPRECATED do not use.
This struct has longs in it
macroTASK_CRASHINFO_RUSAGE_INFO
#define TASK_CRASHINFO_RUSAGE_INFO 0x808
struct rusage_info_v3 from resource.h
macroTASK_CRASHINFO_ARGSLEN
#define TASK_CRASHINFO_ARGSLEN 0x80D
macroTASK_CRASHINFO_EXCEPTION_CODES
#define TASK_CRASHINFO_EXCEPTION_CODES 0x80E
macroTASK_CRASHINFO_WORKQUEUEINFO
#define TASK_CRASHINFO_WORKQUEUEINFO 0x817
struct proc_workqueueinfo
macroTASK_CRASHINFO_LEDGER_INTERNAL_COMPRESSED
#define TASK_CRASHINFO_LEDGER_INTERNAL_COMPRESSED 0x81F
uint64_t
macroTASK_CRASHINFO_LEDGER_ALTERNATE_ACCOUNTING
#define TASK_CRASHINFO_LEDGER_ALTERNATE_ACCOUNTING 0x821
uint64_t
macroTASK_CRASHINFO_LEDGER_ALTERNATE_ACCOUNTING_COMPRESSED
#define TASK_CRASHINFO_LEDGER_ALTERNATE_ACCOUNTING_COMPRESSED 0x822
uint64_t
macroTASK_CRASHINFO_LEDGER_PURGEABLE_NONVOLATILE
#define TASK_CRASHINFO_LEDGER_PURGEABLE_NONVOLATILE 0x823
uint64_t
macroTASK_CRASHINFO_LEDGER_PURGEABLE_NONVOLATILE_COMPRESSED
#define TASK_CRASHINFO_LEDGER_PURGEABLE_NONVOLATILE_COMPRESSED 0x824
uint64_t
macroTASK_CRASHINFO_LEDGER_PHYS_FOOTPRINT_LIFETIME_MAX
#define TASK_CRASHINFO_LEDGER_PHYS_FOOTPRINT_LIFETIME_MAX 0x827
uint64_t
macroTASK_CRASHINFO_LEDGER_NETWORK_NONVOLATILE
#define TASK_CRASHINFO_LEDGER_NETWORK_NONVOLATILE 0x828
uint64_t
macroTASK_CRASHINFO_LEDGER_NETWORK_NONVOLATILE_COMPRESSED
#define TASK_CRASHINFO_LEDGER_NETWORK_NONVOLATILE_COMPRESSED 0x829
uint64_t
macroTASK_CRASHINFO_LEDGER_TAGGED_FOOTPRINT
#define TASK_CRASHINFO_LEDGER_TAGGED_FOOTPRINT 0x82D
uint64_t
macroTASK_CRASHINFO_LEDGER_TAGGED_FOOTPRINT_COMPRESSED
#define TASK_CRASHINFO_LEDGER_TAGGED_FOOTPRINT_COMPRESSED 0x82E
uint64_t
macroTASK_CRASHINFO_LEDGER_MEDIA_FOOTPRINT
#define TASK_CRASHINFO_LEDGER_MEDIA_FOOTPRINT 0x82F
uint64_t
macroTASK_CRASHINFO_LEDGER_MEDIA_FOOTPRINT_COMPRESSED
#define TASK_CRASHINFO_LEDGER_MEDIA_FOOTPRINT_COMPRESSED 0x830
uint64_t
macroTASK_CRASHINFO_LEDGER_GRAPHICS_FOOTPRINT
#define TASK_CRASHINFO_LEDGER_GRAPHICS_FOOTPRINT 0x831
uint64_t
macroTASK_CRASHINFO_LEDGER_GRAPHICS_FOOTPRINT_COMPRESSED
#define TASK_CRASHINFO_LEDGER_GRAPHICS_FOOTPRINT_COMPRESSED 0x832
uint64_t
macroTASK_CRASHINFO_LEDGER_NEURAL_FOOTPRINT
#define TASK_CRASHINFO_LEDGER_NEURAL_FOOTPRINT 0x833
uint64_t
macroTASK_CRASHINFO_LEDGER_NEURAL_FOOTPRINT_COMPRESSED
#define TASK_CRASHINFO_LEDGER_NEURAL_FOOTPRINT_COMPRESSED 0x834
uint64_t
macroTASK_CRASHINFO_MEMORYSTATUS_EFFECTIVE_PRIORITY
#define TASK_CRASHINFO_MEMORYSTATUS_EFFECTIVE_PRIORITY 0x835
macroTASK_CRASHINFO_KERNEL_TRIAGE_INFO_V1
#define TASK_CRASHINFO_KERNEL_TRIAGE_INFO_V1 0x836
struct kernel_triage_info_v1
macroTASK_CRASHINFO_CS_SIGNING_ID
#define TASK_CRASHINFO_CS_SIGNING_ID 0x83B
string of len MAX_CRASHINFO_SIGNING_ID_LEN
macroTASK_CRASHINFO_CS_TEAM_ID
#define TASK_CRASHINFO_CS_TEAM_ID 0x83C
string of len MAX_CRASHINFO_TEAM_ID_LEN
macroTASK_CRASHINFO_CS_VALIDATION_CATEGORY
#define TASK_CRASHINFO_CS_VALIDATION_CATEGORY 0x83D
uint32_t
macroTASK_CRASHINFO_JIT_ADDRESS_RANGE
#define TASK_CRASHINFO_JIT_ADDRESS_RANGE 0x840
struct crashinfo_jit_address_range
macroTASK_CRASHINFO_TASK_SECURITY_CONFIG
#define TASK_CRASHINFO_TASK_SECURITY_CONFIG 0x845
struct task_security_config
macroTASK_CRASHINFO_SANDBOX_PROFILE
#define TASK_CRASHINFO_SANDBOX_PROFILE 0x847
string of len MAX_CRASHINFO_SANDBOX_PROFILE_LEN
macroTASK_CRASHINFO_END
#define TASK_CRASHINFO_END KCDATA_TYPE_BUFFER_END
structbtinfo_thread_state_data_t
tstate is variable length with count elements
| uint32_t | flavor | |
| uint32_t | count | |
| int[] | tstate |
structbtinfo_sc_load_info64
| uint64_t | sharedCacheSlide | |
| uuid_t | sharedCacheUUID | |
| uint64_t | sharedCacheBaseAddress |
structbtinfo_sc_load_info
| uint32_t | sharedCacheSlide | |
| uuid_t | sharedCacheUUID | |
| uint32_t | sharedCacheBaseAddress |
macroTASK_BTINFO_BEGIN
#define TASK_BTINFO_BEGIN KCDATA_BUFFER_BEGIN_BTINFO
macroTASK_BTINFO_PPID
#define TASK_BTINFO_PPID 0xA02
macroTASK_BTINFO_PROC_NAME
#define TASK_BTINFO_PROC_NAME 0xA03
macroTASK_BTINFO_PROC_PATH
#define TASK_BTINFO_PROC_PATH 0xA04
macroTASK_BTINFO_UID
#define TASK_BTINFO_UID 0xA05
macroTASK_BTINFO_GID
#define TASK_BTINFO_GID 0xA06
macroTASK_BTINFO_PROC_FLAGS
#define TASK_BTINFO_PROC_FLAGS 0xA07
macroTASK_BTINFO_CPUTYPE
#define TASK_BTINFO_CPUTYPE 0xA08
macroTASK_BTINFO_EXCEPTION_CODES
#define TASK_BTINFO_EXCEPTION_CODES 0xA09
macroTASK_BTINFO_EXCEPTION_TYPE
#define TASK_BTINFO_EXCEPTION_TYPE 0xA0A
macroTASK_BTINFO_RUSAGE_INFO
#define TASK_BTINFO_RUSAGE_INFO 0xA0B
macroTASK_BTINFO_COALITION_ID
#define TASK_BTINFO_COALITION_ID 0xA0C
macroTASK_BTINFO_CRASH_COUNT
#define TASK_BTINFO_CRASH_COUNT 0xA0D
macroTASK_BTINFO_THROTTLE_TIMEOUT
#define TASK_BTINFO_THROTTLE_TIMEOUT 0xA0E
macroTASK_BTINFO_THREAD_STATE
#define TASK_BTINFO_THREAD_STATE 0xA22
struct btinfo_thread_state_data_t
macroTASK_BTINFO_THREAD_EXCEPTION_STATE
#define TASK_BTINFO_THREAD_EXCEPTION_STATE 0xA23
struct btinfo_thread_state_data_t
macroTASK_BTINFO_DYLD_LOADINFO
#define TASK_BTINFO_DYLD_LOADINFO KCDATA_TYPE_LIBRARY_LOADINFO
macroTASK_BTINFO_DYLD_LOADINFO64
#define TASK_BTINFO_DYLD_LOADINFO64 KCDATA_TYPE_LIBRARY_LOADINFO64
macroTASK_BTINFO_FLAG_BT_TRUNCATED
#define TASK_BTINFO_FLAG_BT_TRUNCATED 0x1
macroTASK_BTINFO_FLAG_ASYNC_BT_TRUNCATED
#define TASK_BTINFO_FLAG_ASYNC_BT_TRUNCATED 0x2
macroTASK_BTINFO_FLAG_KCDATA_INCOMPLETE
#define TASK_BTINFO_FLAG_KCDATA_INCOMPLETE 0x8
lw corpse collection is incomplete
macroTASK_BTINFO_END
#define TASK_BTINFO_END KCDATA_TYPE_BUFFER_END
macroEXIT_REASON_SNAPSHOT
#define EXIT_REASON_SNAPSHOT 0x1001
macroEXIT_REASON_CODESIGNING_INFO
#define EXIT_REASON_CODESIGNING_INFO 0x1004
macroEXIT_REASON_WORKLOOP_ID
#define EXIT_REASON_WORKLOOP_ID 0x1005
macroEXIT_REASON_DISPATCH_QUEUE_NO
#define EXIT_REASON_DISPATCH_QUEUE_NO 0x1006
structexit_reason_snapshot
| uint32_t | ers_namespace | |
| uint64_t | ers_code | |
| uint64_t | ers_flags | end of version 1 of exit_reason_snapshot. sizeof v1 was 12 |
macroEXIT_REASON_CODESIG_PATH_MAX
#define EXIT_REASON_CODESIG_PATH_MAX 1024
structcodesigning_exit_reason_info
| uint64_t | ceri_virt_addr | |
| uint64_t | ceri_file_offset | |
| char[1024] | ceri_pathname | |
| char[1024] | ceri_filename | |
| uint64_t | ceri_codesig_modtime_secs | |
| uint64_t | ceri_codesig_modtime_nsecs | |
| uint64_t | ceri_page_modtime_secs | |
| uint64_t | ceri_page_modtime_nsecs | |
| uint8_t | ceri_path_truncated | |
| uint8_t | ceri_object_codesigned | |
| uint8_t | ceri_page_codesig_validated | |
| uint8_t | ceri_page_codesig_tainted | |
| uint8_t | ceri_page_codesig_nx | |
| uint8_t | ceri_page_wpmapped | |
| uint8_t | ceri_page_slid | |
| uint8_t | ceri_page_dirty | |
| uint32_t | ceri_page_shadow_depth |
macroEXIT_REASON_USER_DESC_MAX_LEN
#define EXIT_REASON_USER_DESC_MAX_LEN 1024
macroEXIT_REASON_PAYLOAD_MAX_LEN
#define EXIT_REASON_PAYLOAD_MAX_LEN 2048
structkcdata_iter
| kcdata_item_t | item | |
| void * | end |
typedefkcdata_iter_t
typedef struct kcdata_iter kcdata_iter_t;
functionkcdata_iter
static inline kcdata_iter_t kcdata_iter(void *buffer, unsigned long size)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns an iterator over a kcdata buffer of the given size, positioned at the first item. kcdata is the self-describing, type-tagged serialization format produced by stackshot, corpse/crash info, and the kern_cdata interfaces. Check the position with kcdata_iter_valid, advance with kcdata_iter_next or the KCDATA_ITER_FOREACH macro, and inspect items with kcdata_iter_type / kcdata_iter_size / kcdata_iter_payload.
functionkcdata_iter_unsafe
__attribute__((deprecated)) static inline kcdata_iter_t kcdata_iter_unsafe(void *buffer)
deprecated
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Deprecated. Returns an iterator over the kcdata buffer with no end bound, so kcdata_iter_valid can never detect a runaway or truncated buffer. Use kcdata_iter with an explicit buffer size instead.
functionkcdata_iter_unsafe
static inline kcdata_iter_t kcdata_iter_unsafe(void *buffer)
deprecated
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Deprecated. Returns an iterator over the kcdata buffer with no end bound, so kcdata_iter_valid can never detect a runaway or truncated buffer. Use kcdata_iter with an explicit buffer size instead.
variablekcdata_invalid_iter
static const kcdata_iter_t kcdata_invalid_iter = { .item = NULL, .end = NULL }
functionkcdata_iter_valid
static inline int kcdata_iter_valid(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns nonzero if the iterator points at a complete item: both the kcdata_item header and the payload length it declares lie within the buffer bounds. Must be checked before any other accessor and after each kcdata_iter_next.
functionkcdata_iter_next
static inline kcdata_iter_t kcdata_iter_next(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns an iterator advanced past the current item (header plus declared payload size). The result must be validated with kcdata_iter_valid before use; iteration normally ends at a KCDATA_TYPE_BUFFER_END item.
functionkcdata_iter_type
static inline uint32_t kcdata_iter_type(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the type tag of the current item. The KCDATA_TYPE_ARRAY_PAD0 through _PADf variants, which encode the array padding in the low nibble of the type, are all reported as KCDATA_TYPE_ARRAY.
functionkcdata_calc_padding
static inline uint32_t kcdata_calc_padding(uint32_t size)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the number of bytes that must be added to size to round it up to a 16-byte boundary, the alignment kcdata items are padded to.
functionkcdata_flags_get_padding
static inline uint32_t kcdata_flags_get_padding(uint64_t flags)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Extracts the trailing struct padding byte count from an item's flags word (KCDATA_FLAGS_STRUCT_PADDING_MASK, the low 4 bits). kcdata_iter_size subtracts this from the stored size to recover the unpadded payload size.
functionkcdata_iter_is_legacy_item
static inline int kcdata_iter_is_legacy_item(kcdata_iter_t iter, uint32_t legacy_size)
see comment above about has_padding
functionkcdata_iter_size
static inline uint32_t kcdata_iter_size(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the payload size in bytes of the current item, with the trailing padding recorded in the item flags subtracted out. Array and container-begin items report their stored size unchanged. STACKSHOT_KCTYPE_THREAD_SNAPSHOT and STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO are special-cased to their legacy struct sizes for buffers from kernels that predate the padding flags.
functionkcdata_iter_flags
static inline uint64_t kcdata_iter_flags(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the 64-bit flags word of the current item. Its meaning is type-dependent: padding bits for struct items, element type and count for arrays, container ID for containers.
functionkcdata_iter_payload
static inline void * kcdata_iter_payload(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns a pointer to the payload of the current item, immediately following the kcdata_item header.
functionkcdata_iter_array_elem_type
static inline uint32_t kcdata_iter_array_elem_type(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the element type of the current array item, stored in the upper 32 bits of the item's flags word.
functionkcdata_iter_array_elem_count
static inline uint32_t kcdata_iter_array_elem_count(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the number of elements in the current array item, stored in the lower 32 bits of the item's flags word.
functionkcdata_iter_array_size_switch
static inline uint32_t kcdata_iter_array_size_switch(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the fixed element size for legacy KCDATA_TYPE_ARRAY items, keyed by element type (dyld_uuid_info_32/64 load info, 32- and 64-bit stack frames, thread delta snapshots, ...), or 0 for any type not in the fixed list. Legacy arrays padded their total size without recording the padding, so element size cannot be derived from the item size; an array whose element type is unknown to this switch must be treated as invalid. Newer kernels emit KCDATA_TYPE_ARRAY_PAD* instead, which records the padding explicitly.
functionkcdata_iter_array_valid
static inline int kcdata_iter_array_valid(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns nonzero if the current item is a well-formed array: the iterator is valid, the type is KCDATA_TYPE_ARRAY, and the recorded element count is consistent with the item size and padding. Legacy KCDATA_TYPE_ARRAY items must additionally have an element type with a known fixed size (kcdata_iter_array_size_switch); for KCDATA_TYPE_ARRAY_PAD* items the padding recorded in the type nibble is checked instead.
functionkcdata_iter_array_elem_size
static inline uint32_t kcdata_iter_array_elem_size(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the size in bytes of one element of the current array item: the fixed legacy size for KCDATA_TYPE_ARRAY items, otherwise the item size minus the padding recorded in the type nibble, divided by the element count.
functionkcdata_iter_container_valid
static inline int kcdata_iter_container_valid(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns nonzero if the current item is a valid KCDATA_TYPE_CONTAINER_BEGIN item whose payload holds at least the uint32_t container type.
functionkcdata_iter_container_type
static inline uint32_t kcdata_iter_container_type(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the container type (e.g. STACKSHOT_KCCONTAINER_TASK, STACKSHOT_KCCONTAINER_THREAD) stored in the payload of the current KCDATA_TYPE_CONTAINER_BEGIN item.
functionkcdata_iter_container_id
static inline uint64_t kcdata_iter_container_id(kcdata_iter_t iter)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns the 64-bit container identifier of the current container-begin item, taken from its flags word. The matching KCDATA_TYPE_CONTAINER_END item carries the same identifier, allowing nested containers to be paired.
macroKCDATA_ITER_FOREACH
#define KCDATA_ITER_FOREACH(iter) for(; kcdata_iter_valid(iter) && iter.item->type != KCDATA_TYPE_BUFFER_END; iter = kcdata_iter_next(iter))
macroKCDATA_ITER_FOREACH_FAILED
#define KCDATA_ITER_FOREACH_FAILED(iter) (!kcdata_iter_valid(iter) || (iter).item->type != KCDATA_TYPE_BUFFER_END)
functionkcdata_iter_find_type
static inline kcdata_iter_t kcdata_iter_find_type(kcdata_iter_t iter, uint32_t type)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Scans forward from the iterator's current position and returns an iterator positioned at the first item whose type matches type. Returns an invalid iterator if no match is found before KCDATA_TYPE_BUFFER_END or the end of the buffer.
functionkcdata_iter_data_with_desc_valid
static inline int kcdata_iter_data_with_desc_valid(kcdata_iter_t iter, uint32_t minsize)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns nonzero if the current item is a valid description-tagged item (KCDATA_TYPE_STRING_DESC, KCDATA_TYPE_UINT64_DESC, KCDATA_TYPE_BINDATA_DESC, ...): its payload holds at least KCDATA_DESC_MAXLEN (32) bytes of NUL-terminated description followed by at least minsize bytes of data.
functionkcdata_iter_string
static inline char * kcdata_iter_string(kcdata_iter_t iter, uint32_t offset)
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
Returns a pointer to the NUL-terminated string beginning at offset within the current item's payload, or NULL if offset is beyond the item or the string is not terminated within the item's bounds.
functionkcdata_iter_get_data_with_desc
static inline void kcdata_iter_get_data_with_desc( kcdata_iter_t iter, char **desc_ptr, void **data_ptr, uint32_t *size_ptr )
▾
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu osfmk/kern/kcdata.h
For a description-tagged item, returns through the non-NULL out parameters the description string (the first KCDATA_DESC_MAXLEN bytes of the payload), a pointer to the data that follows it, and the size of that data. Validate the item with kcdata_iter_data_with_desc_valid first; any of desc_ptr, data_ptr, and size_ptr may be NULL.