Kernel Debugging on Apple Silicon

Notes on how I was able to debug my kernel extension on a 2020 M1 Mini.

As of Mar 2021, kernel debugging on Apple Silicon is rather primitive compared to Intel. All you can do right now is inspect the current state of the kernel when it has halted due to a panic or non maskable interrupt (NMI). You can’t set breakpoints, step into code or continue post NMI.

Setup

You need two Macs.

The target device is the Mac that runs the code you want to debug.

The host device is the Mac that runs the debugger.

Download the appropriate Kernel Debug Kit (KDK) from Apple. Make sure that the build number matches the build number of the target device(sw_vers is your friend). Install the KDK on your host device. Make sure to print out the instructions that come up as part of the installer. Read the docs carefully at least once from end to end. I hate to waste trees, but I found it nice to be able to take notes on the doc, and to have them to review while I was rebooting (multiple times).

Not all KDKs are created equal. I found that some versions of the KDK didn’t contain the kernel I needed for the M1 Mini. The KDK installs the kernels it will work for in Library/Developer/KDKs/KDK_<OS_Version>_<BUILD>.kdk/System/Library/Kernels/. You will find multiple kernels in there. For my stock M1 I needed to have the kernel.release.t8101 version. You can determine the version you need be running uname -v on the target machine. If the KDK doesn’t have the version you need, you may need to install a different OS on your target machine.

I set up my debugging setup with a direct ethernet cable from my host to target machine.

  • Configure IPv4: Manually
  • IP Address: 10.0.0.1
  • Subnet Mask: 255.255.255.0
  • Configure IPv4: Manually
  • IP Address: 10.0.0.2
  • Subnet Mask: 255.255.255.0

The rest of the instructions in the Kernel Debug Kit for macOS-Read Me are pretty good and I won’t repeat them here. It is worth noting though that they never mention the NMI keyboard sequence which is: cmd-opt-ctrl-shift-esc

Also not mentioned in the read me is that there are a bunch of very useful lldb macros that you are going to want to use. Python version 3 is not supported for these macros, so you need to configure lldb to use python 2 before you launch lldb.

defaults write com.apple.dt.lldb DefaultPythonVersion 2

Once you’ve loaded lldb (and before you hit an NMI/panic or load a core file) you will also want

settings set target.load-script-from-symbol-file true

so that the macros are loaded for you automatically. This is worth considering adding to your .lldbinit file so it happens by default. If you don’t set this before you load the core file it may not symbolicate correctly for you.

Make sure that the dsym for your kext is available to lldb on your host machine.

Core files take a while to transfer (multiple minutes). You will need to chown them and extract them appropriately once they’ve transferred.

Once you’ve hit the panic, or loaded the core file make sure to run help to see all the extra macros you now have in lldb. The source for the macros is available in /Library/Developer/KDKs/KDK_<VERSION>.kdk/System/Library/Kernels/kernel.release.t8101.dSYM/Contents/Resources/Python/lldbmacros/

Kernel variants

The Readme claims these don’t work on Apple Silicon, but I’ve noticed that they are included in my version of the KDK. Please let me know if you try them out.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store