Kernel debugging and panic API
The kernel debugging interface: the panic() family, the Debugger() entry point, stackshot triggering, debug-mode and panic-state queries, and the panic-data buffer registration used to attach extra state to panic logs.
thread_snapshot source struct · thread_snapshot reference
struct thread_snapshot { uint32_t snapshot_magic; uint32_t nkern_frames; uint32_t nuser_frames; uint64_t wait_event; uint64_t continuation; uint64_t thread_id; uint64_t user_time; uint64_t system_time; int32_t state; int32_t priority; /* static priority */ int32_t sched_pri; /* scheduled (current) priority */ int32_t sched_flags; /* scheduler flags */ char ss_flags; char ts_qos; /* effective qos */ char ts_rqos; /* requested qos */ char ts_rqos_override; /* requested qos override */ char io_tier; /* * In microstackshots, the low two bytes are the start of the first async * frame in the thread's user space call stack. If the call stack lacks * async stack frames, it's `UINT16_MAX`. */ char _reserved[3]; /* pad for 4 byte alignement packing */ /* * I/O Statistics * XXX: These fields must be together */ uint64_t disk_reads_count; … more in source
task_snapshot source struct · task_snapshot reference
old, non kcdata format
struct task_snapshot { uint32_t snapshot_magic; int32_t pid; uint64_t uniqueid; uint64_t user_time_in_terminated_threads; uint64_t system_time_in_terminated_threads; uint8_t shared_cache_identifier[16]; uint64_t shared_cache_slide; uint32_t nloadinfos; int suspend_count; int task_size; /* pages */ int faults; /* number of page faults */ int pageins; /* number of actual pageins */ int cow_faults; /* number of copy-on-write faults */ uint32_t ss_flags; /* * In microstackshots, `p_start_sec` is actually the resource coalition ID * that this thread belongs to. */ uint64_t p_start_sec; /* from the bsd proc struct */ /* * In microstackshots, `p_stat_usec` is actually the resource coalition ID * that this thread is doing work on behalf of. */ uint64_t p_start_usec; /* from the bsd proc struct */ /* * We restrict ourselves to a statically defined * (current as of 2009) length for the * p_comm string, due to scoping issues (osfmk/bsd and user/kernel … more in source
micro_snapshot source struct · micro_snapshot reference
struct micro_snapshot { uint32_t snapshot_magic; uint32_t ms_cpu; /* cpu number this snapshot was recorded on */ uint64_t ms_time; /* time at sample (seconds) */ uint64_t ms_time_microsecs; uint8_t ms_flags; uint16_t ms_opaque_flags; /* managed by external entity, e.g. fdrmicrod */ }
_dyld_cache_header source struct · _dyld_cache_header reference
mirrors the dyld_cache_header struct defined in dyld_cache_format.h from dyld source code
struct _dyld_cache_header { char magic[16]; // e.g. "dyld_v0 i386" uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info uint32_t mappingCount; // number of dyld_cache_mapping_info entries uint32_t imagesOffset; // file offset to first dyld_cache_image_info uint32_t imagesCount; // number of dyld_cache_image_info entries uint64_t dyldBaseAddress; // base address of dyld when cache was built uint64_t codeSignatureOffset;// file offset of code signature blob uint64_t codeSignatureSize; // size of code signature blob (zero means to end of file) uint64_t slideInfoOffset; // file offset of kernel slid info uint64_t slideInfoSize; // size of kernel slid info uint64_t localSymbolsOffset; // file offset of where local symbols are stored uint64_t localSymbolsSize; // size of local symbols information uint8_t uuid[16]; // unique value for each shared cache file uint64_t cacheType; // 0 for development, 1 for production uint32_t branchPoolsOffset; // file offset to table of uint64_t pool addresses uint32_t branchPoolsCount; // number of uint64_t entries uint64_t accelerateInfoAddr; // (unslid) address of optimization info uint64_t accelerateInfoSize; // size of optimization info uint64_t imagesTextOffset; // file offset to first dyld_cache_image_text_info uint64_t imagesTextCount; // number of dyld_cache_image_text_info entries uint64_t dylibsImageGroupAddr;// (unslid) address of ImageGroup for dylibs in this cache uint64_t dylibsImageGroupSize;// size of ImageGroup for dylibs in this cache uint64_t otherImageGroupAddr;// (unslid) address of ImageGroup for other OS dylibs uint64_t otherImageGroupSize;// size of oImageGroup for other OS dylibs uint64_t progClosuresAddr; // (unslid) address of list of program launch closures uint64_t progClosuresSize; // size of list of program launch closures uint64_t progClosuresTrieAddr;// (unslid) address of trie of indexes into program launch closures uint64_t progClosuresTrieSize;// size of trie of indexes into program launch closures uint32_t platform; // platform number (macOS=1, etc) … more in source
_dyld_cache_image_text_info source struct · _dyld_cache_image_text_info reference
mirrors the dyld_cache_image_text_info struct defined in dyld_cache_format.h from dyld source code
struct _dyld_cache_image_text_info { uuid_t uuid; uint64_t loadAddress; // unslid address of start of __TEXT uint32_t textSegmentSize; uint32_t pathOffset; // offset from start of cache file }
micro_snapshot_flags source enum · micro_snapshot_flags reference
enum micro_snapshot_flags { /* * (Timer) interrupt records are no longer supported. */ kInterruptRecord = 0x01, /* * Timer arming records are no longer supported. */ kTimerArmingRecord = 0x02, kUserMode = 0x04, /* interrupted usermode, or armed by usermode */ kIORecord = 0x08, kPMIRecord = 0x10, kMACFRecord = 0x20, /* armed by MACF policy */ kKernelThread = 0x40, /* sampled a kernel thread */ }
generic_snapshot_flags source enum · generic_snapshot_flags reference
Flags used in the following assortment of snapshots.
enum generic_snapshot_flags { kUser64_p = 0x1, /* Userspace uses 64 bit pointers */ kKernel64_p = 0x2 /* The kernel uses 64 bit pointers */ }
embedded_panic_header source struct · embedded_panic_header reference
Any updates to this header should be also updated in astris as it can not
grab this header from the SDK.
NOTE: DO NOT REMOVE OR CHANGE THE MEANING OF ANY FIELDS FROM THIS STRUCTURE.
Any modifications should add new fields at the end, bump the version number
and be done alongside astris and DumpPanic changes.
struct embedded_panic_header { uint32_t eph_magic; /* EMBEDDED_PANIC_MAGIC if valid */ uint32_t eph_crc; /* CRC of everything following the ph_crc in the header and the contents */ uint32_t eph_version; /* embedded_panic_header version */ eph_panic_flags_t eph_panic_flags; /* Flags indicating any state or relevant details */ uint32_t eph_panic_log_offset; /* Offset of the beginning of the panic log from the beginning of the header */ uint32_t eph_panic_log_len; /* length of the panic log */ uint32_t eph_stackshot_offset; /* Offset of the beginning of the panic stackshot from the beginning of the header */ uint32_t eph_stackshot_len; /* length of the panic stackshot (0 if not valid ) */ uint32_t eph_other_log_offset; /* Offset of the other log (any logging subsequent to the stackshot) from the beginning of the header */ uint32_t eph_other_log_len; /* length of the other log */ union { struct { uint64_t eph_x86_power_state:8, eph_x86_efi_boot_state:8, eph_x86_system_state:8, eph_x86_unused_bits:40; }; // anonymous struct to group the bitfields together. uint64_t eph_x86_do_not_use; /* Used for offsetof/sizeof when parsing header */ } __attribute__((packed)); char eph_os_version[EMBEDDED_PANIC_HEADER_OSVERSION_LEN]; char eph_macos_version[EMBEDDED_PANIC_HEADER_OSVERSION_LEN]; uuid_string_t eph_bootsessionuuid_string; /* boot session UUID */ uint64_t eph_roots_installed; /* bitmap indicating which roots are installed on this system */ uint32_t eph_ext_paniclog_offset; uint32_t eph_ext_paniclog_len; uint32_t eph_panic_initiator_offset; uint32_t eph_panic_initiator_len; }
macos_panic_header source struct · macos_panic_header reference
struct macos_panic_header { uint32_t mph_magic; /* MACOS_PANIC_MAGIC if valid */ uint32_t mph_crc; /* CRC of everything following mph_crc in the header and the contents */ uint32_t mph_version; /* macos_panic_header version */ uint32_t mph_padding; /* unused */ mph_panic_flags_t mph_panic_flags; /* Flags indicating any state or relevant details */ uint32_t mph_panic_log_offset; /* Offset of the panic log from the beginning of the header */ uint32_t mph_panic_log_len; /* length of the panic log */ uint32_t mph_stackshot_offset; /* Offset of the panic stackshot from the beginning of the header */ uint32_t mph_stackshot_len; /* length of the panic stackshot */ uint32_t mph_other_log_offset; /* Offset of the other log (any logging subsequent to the stackshot) from the beginning of the header */ uint32_t mph_other_log_len; /* length of the other log */ uint64_t mph_roots_installed; /* bitmap indicating which roots are installed on this system */ char mph_data[]; /* panic data -- DO NOT ACCESS THIS FIELD DIRECTLY. Use the offsets above relative to the beginning of the header */ }
efi_aurr_panic_header source struct · efi_aurr_panic_header reference
Any change to the below structure should mirror the structure defined in MacEFIFirmware
(and vice versa)
struct efi_aurr_panic_header { uint32_t efi_aurr_magic; uint32_t efi_aurr_crc; uint32_t efi_aurr_version; uint32_t efi_aurr_reset_cause; uint32_t efi_aurr_reset_log_offset; uint32_t efi_aurr_reset_log_len; char efi_aurr_panic_data[]; }
efi_aurr_extended_panic_log source struct · efi_aurr_extended_panic_log reference
struct efi_aurr_extended_panic_log { char efi_aurr_extended_log_buf[EFI_AURR_EXTENDED_LOG_SIZE]; uint32_t efi_aurr_log_tail; /* Circular buffer indices */ uint32_t efi_aurr_log_head; /* ditto.. */ }
additional_panic_data_buffer source struct
limit the max size to a reasonable length
struct additional_panic_data_buffer { const char *producer_name; void *buf; int len; }
kdp_core_encryption_key_descriptor source struct
struct kdp_core_encryption_key_descriptor { uint64_t kcekd_format; uint16_t kcekd_size; void * kcekd_key; }
panic_lockdown_initiator_state source struct
Exclaves stackshot tests support
struct panic_lockdown_initiator_state { /** The PC from which panic lockdown was initiated. */ uint64_t initiator_pc; /** The SP from which panic lockdown was initiated. */ uint64_t initiator_sp; /** The TPIDR of the initiating CPU. */ uint64_t initiator_tpidr; /** The MPIDR of the initating CPU. */ uint64_t initiator_mpidr; /** The timestamp (from CNTVCT_EL0) at which panic lockdown was initiated. */ uint64_t timestamp; /* * Misc. exception information. */ uint64_t esr; uint64_t elr; uint64_t far; }
kernel_panic_reason_t source typedef
typedef struct kernel_panic_reason { char buf[1024]; } *kernel_panic_reason_t;debugger_op source typedef
typedef enum { DBOP_NONE, DBOP_STACKSHOT, DBOP_RESET_PGO_COUNTERS, DBOP_PANIC, DBOP_DEBUGGER, DBOP_BREAKPOINT, } debugger_op;IOCoreFileAccessCallback source typedef
A callback that reads or writes data from a given offset into the corefile. It is understood that this
callback should only be used from within the context where it is given. It should never be stored and
reused later on.
typedef kern_return_t (*IOCoreFileAccessCallback)(void *context, boolean_t write, uint64_t offset, int length, void *buffer);
IOCoreFileAccessRecipient source typedef
A callback that receives temporary file-system access to the kernel corefile
Parameters:
- access: A function to call for reading/writing the kernel corefile.
- access_context: The context that should be passed to the 'access' function.
- recipient_context: The recipient-specific context. Can be anything.
typedef kern_return_t (*IOCoreFileAccessRecipient)(IOCoreFileAccessCallback access, void *access_context, void *recipient_context);
lbr_modes_t source typedef
Enum of allowed values for the 'lbr_support' boot-arg
typedef enum { LBR_ENABLED_NONE, LBR_ENABLED_USERMODE, LBR_ENABLED_KERNELMODE, LBR_ENABLED_ALLMODES } lbr_modes_t;debug_is_current_cpu_in_panic_state source
extern boolean_t debug_is_current_cpu_in_panic_state(void);
phys_carveout_init source
Initialize the physical carveout requested with the `phys_carveout_mb`
boot-arg. This should only be called at kernel startup, when physically
contiguous pages are plentiful.
extern void phys_carveout_init(void);
debug_is_in_phys_carveout source
Check whether a kernel virtual address points within the physical carveout.
extern boolean_t debug_is_in_phys_carveout(vm_map_offset_t va);
debug_can_coredump_phys_carveout source
Check whether the physical carveout should be included in a coredump.
extern boolean_t debug_can_coredump_phys_carveout(void);
zone_leaks source
extern kern_return_t zone_leaks(const char * zoneName, uint32_t nameLen, leak_site_proc proc);
zone_leaks_scan source
extern void zone_leaks_scan(uintptr_t * instances, uint32_t count, uint32_t zoneSize, uint32_t * found);
IOProvideCoreFileAccess source
Provides safe and temporary file-system access to the kernel corefile to the given recipient callback.
It does so by opening the kernel corefile, then calling the 'recipient' callback, passing it an IOCoreFileAccessCallback
function that it can use to read/write data, then closing the kernel corefile as soon as the recipient returns.
Parameters:
- recipient: A function to call, providing it access to the kernel corefile.
- recipient_context: Recipient-specific context. Can be anything.
extern kern_return_t IOProvideCoreFileAccess(IOCoreFileAccessRecipient recipient, void *recipient_context);
panic_lockdown_record_debug_data source
Attempt to record debug state for a panic lockdown event
extern void panic_lockdown_record_debug_data(void);