Finally, a kext that dumps kernel debug messages to a file for later analysis without the need of a serial connection or screen capture. Also useful on recoveryOS or the installer stage.
- An x86_64 (Intel/AMD) based Hackintosh or Mac.
- OpenCore bootloader (recommended, duh).
- macOS Monterey or newer (possibly lower too, but untested).
- Clone the repository:
git clone https://github.com/hg13bs/KernelDebugger - Initalize submodules:
git submodule update --init --recursive - Open
KernelDebugger.xcodeprojin Xcode or build usingxcodebuildfrom the command line (e.g.xcodebuild -scheme KernelDebugger -configuration Release).
- Download the latest release from the Releases page.
This kext comes with a number of boot arguments to control its behavior. Add them to your bootloader's boot-args variable as needed.
-krnldbgoff: Disable the kext entirely.-krnldbgbeta: Force loading on unsupported macOS versions (use with caution).-krnldbgdebug: Enable debug logging for the kext itself.
-krnldbglogdisable: Disable file logging (ring buffer still captures messages).-krnldbglogtmp: Force log output to/private/var/tmp/krnl.log.-krnldbgloginitfast: Begin file creation immediately at boot (skip the default 5-second uptime wait).-krnldbglogopport: Flush to disk on every log write instead of waiting for the timer (higher I/O, lower latency).-krnldbglogbig: Use a large 16 MB ring buffer (same askrnldbglogbufmb=16).
krnldbglogpath(string, default:/var/log/krnl.log): Full path for the log file.krnldbglogname(string, default:krnl.log): Override just the log filename (used with volume/dir modes).krnldbglogrel(string, default: none): Short relative/absolute path (avoids long NVRAM strings).krnldbglogdir(string, default: none): Directory path; the log filename is appended automatically.krnldbglogvol(string, default: none): Volume name to search for under/Volumes/(e.g.USBfinds/Volumes/USB).krnldbglogbsd(string, default: none): BSD device name to resolve mount point (e.g.disk2s1).
Volume resolution: When using
krnldbglogvolorkrnldbglogbsd, the kext iterates mounted filesystems until the target appears, with automatic fallback to/private/var/tmp/krnl.logafter ~60 retries. APFS data-volume variants (e.g.Name - Data) and numbered duplicates (Name 1) are matched automatically.
krnldbglogbuf(uint32KB, default:16384): Ring buffer size in KB (range: 64–256000).krnldbglogbufmb(uint32MB, default:16): Ring buffer size in MB (range: 1–250, overrideskrnldbglogbuf).krnldbglogint(uint32ms, default:1000): Flush timer interval in milliseconds.krnldbglogthresh(uint32bytes, default:8192): Minimum buffered bytes before a non-forced flush writes to disk.
-
Not all log sources may be captured, especially early boot messages before the kext initializes and including some user-space logs that don't go through the hooked functions.
-
File I/O is performed in a workqueue context, which may be deferred during heavy system load or panic conditions.
-
For others, see the Issues page.
- Apple for macOS (duh)
- Acidanthera for Lilu/MacKernelSDK
- Anthropic for Claude, which was used to help with the kext implementation and code documentation.