Kernel debugging and panic API

osfmk/kern/debug.h · 988 lines · browse source

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_putc source
extern void debug_putc(char);
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);