Last active
July 8, 2022 10:48
-
-
Save Superbil/7508a6d25f13dbadda48962aceb28e25 to your computer and use it in GitHub Desktop.
Kernel Debug Kit 11.0 build 20A5374i
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Kernel Debug Kit for macOS - Read Me | |
Use the Kernel Debug Kit (KDK) to debug kernel-level code, such as kernel extensions you create. | |
Performing Two-Machine Debugging | |
The KDK supports the debugging of kernel-level code, such as kernel extensions, from a second Mac. | |
- The target device is the Mac that runs the code you want to debug. | |
- The host device is the Mac that runs the debugger. | |
Identify the Device Compatibility | |
On Apple silicon, perform two-machine debugging using your Mac’s built-in Ethernet ports. | |
On Intel-based Mac computers, perform two-machine debugging using your Mac’s built-in Ethernet ports, the Ethernet port on the Apple Thunderbolt display, or the Apple Thunderbolt to Gigabit Ethernet adapter. You may also use third-party Thunderbolt Ethernet adapters that support one of the following chipsets: | |
• Broadcom C-IV | |
• Aquantia AQC107/113 | |
• Intel 82574L | |
Note: You cannot perform two-machine debugging using USB Ethernet adapters or wireless networking on any Mac. | |
You must connect the host and target device to the same network, but there are no other restrictions on how the devices connect to that network. | |
Configure an Apple Silicon Mac as a Target Device | |
Use the following steps to configure your Apple silicon Mac as a target device for debugging. | |
Step 1: Modify the Security Configuration of Your Mac | |
Modify the security configuration of your system as follows: | |
1. Reboot your system in Recovery Mode. | |
2. Set the Boot Policy to “Reduced Security”. | |
⁃ If you are debugging a kernel extension, you will also need to enable kernel extensions from identified developers. | |
3. Launch Terminal and run the following command to disable System Integrity Protection (SIP): | |
⁃ csrutil disable | |
4. Reboot your Mac computer. | |
Step 2: Identify the Correct Ethernet Device | |
Run the ifconfig tool in Terminal to identify which Ethernet device your target device uses to connect to the network. In the following example, en1 is the Ethernet device connected to the network. | |
en0: flags=8963 mtu 1500 options=60 ether 32:00:13:er:19:e0 media: autoselect status: inactive en1: flags=8863 mtu 1500 options=10b ether 40:6c:8f:5b:a2:96 inet6 fe80::426c:8fff:fe5b:a296%en2 prefixlen 64 scopeid 0x4 inet6 2620::1b07:114:426c:8fff:fe5b:a296 prefixlen 64 autoconf inet6 2620::1b07:114:88d6:bbba:7ac9:b0a7 prefixlen 64 autoconf temporary inet 10.128.19.135 netmask 0xfffff800 broadcast 10.128.23.255 nd6 options=1 media: autoselect (1000baseT ) status: active | |
Step 3: Set the boot-args | |
Run the nvram tool in Terminal to update your target device’s boot args. Include the following keys: | |
• debug=0x44—Tells the kernel to wait for a debugger to attach to the device, when the kernel receives a non-maskable interrupt (NMI). | |
• kdp_match_name=enX—Set the value of this key to the Ethernet device (en0, en1, etc.) identified in Step 2: Identify the Correct Ethernet Device. | |
• wdt=-1—Disables watchdog monitoring. | |
For example: | |
sudo nvram boot-args=“debug=0x44 kdp_match_name=en1 wdt=-1” | |
Step 4: Reboot the Device | |
Upon reboot, you may connect to your target device from the host. | |
Configure an Intel-Based Mac as a Target Device | |
Use the following steps to configure your target device for debugging. | |
Step 1: Modify the Security Configuration of Your Mac | |
Modify the security configuration of your system as follows: | |
1. Reboot your system in Recovery Mode. | |
2. If your device has the Apple T2 Security Chip, set the Secure Boot policy to “Medium Security”. | |
3. Launch Terminal and run the following command to disable System Integrity Protection (SIP): | |
⁃ csrutil disable | |
4. Reboot your Mac computer. | |
Step 2: Identify the Correct Ethernet Device | |
Run the ifconfig tool in Terminal to identify which Ethernet device your target device uses to connect to the network. In the following example, en1 is the Ethernet device connected to the network. | |
en0: flags=8963 mtu 1500 options=60 ether 32:00:13:er:19:e0 media: autoselect status: inactive en1: flags=8863 mtu 1500 options=10b ether 40:6c:8f:5b:a2:96 inet6 fe80::426c:8fff:fe5b:a296%en2 prefixlen 64 scopeid 0x4 inet6 2620::1b07:114:426c:8fff:fe5b:a296 prefixlen 64 autoconf inet6 2620::1b07:114:88d6:bbba:7ac9:b0a7 prefixlen 64 autoconf temporary inet 10.128.19.135 netmask 0xfffff800 broadcast 10.128.23.255 nd6 options=1 media: autoselect (1000baseT ) status: active | |
Step 3: Set the boot-args | |
Run the nvram tool in Terminal to update your target device’s boot args. Include the following keys: | |
• debug=0x44—Tells the kernel to wait for a debugger to attach to the device, when the kernel receives a non-maskable interrupt (NMI). | |
• kdp_match_name=enX—Set the value of this key to the Ethernet device (en0, en1, etc.) identified in Step 2: Identify the Correct Ethernet Device. | |
• wdt=-1—Disables watchdog monitoring. | |
For example: | |
sudo nvram boot-args=“debug=0x44 kdp_match_name=en1 wdt=-1” | |
Step 4: Reboot the Device | |
Upon reboot, you may connect to your target device from the host. | |
Configure the Host Device | |
Configure your host device to initiate debugging using the following steps: | |
Step 1: Install Xcode 12 or later | |
Install Xcode, including the command-line tools, on the host device. | |
Step 2: Install the KDK | |
Install this KDK on the host device. | |
Trigger the Target Device to Wait for the Debugger | |
After you configure the target device, it halts and waits for an external debugger to attach in the following situations: | |
• If the target device panics, it automatically halts and waits for an external debugger to attach. | |
• If you trigger an NMI on the target device, the device halts and waits for an external debugger to attach. | |
Connect the Debugger to the Target Device | |
Run lldb from Terminal and use the kdp-remote command to connect to the target device. That command accepts the hostname or IP address of the target device, and creates a debugger connection to it. | |
(lldb)kdp-remote {name_or_ip_address} | |
To generate a core dump of the target system, enter the file command and use the -c option to specify where to store the resulting file. | |
(lldb)file -c /tmp/mycorefile | |
The lldb tool automatically searches any spotlight-indexed directories and the /Library/Developer/KDKs/ directory on the local system for symbol information. You can specify the location of the kernel symbol files by including the path to the kernel file on the command line when you launch lldb. For example: | |
%lldb /Library/Developer/KDKs/<KDK Version>/System/Library/Kernels/kernel | |
Apple silicon-based Mac computers don’t support active kernel debugging. You may inspect the current state of the kernel when it is halted due to a panic or NMI. However, you cannot set breakpoints, continue code execution, step into code, step over code, or step out of the current instruction. | |
Finish Up Your Debugging Session | |
When you finish debugging the target device, quit lldb to disconnect the host from the target machine. | |
When you no longer need to debug the target device, return the device to normal operation: | |
1. Remove the boot args using the nvram tool: | |
⁃ sudo nvram -d boot-args | |
2. Re-enable SIP and restore your Boot Policy on Apple Silicon Macs or your Secure Boot policy on Intel Macs. | |
Installing Kernel and Kernel Extension Variants | |
The KDK includes several variants of the kernel binary and kernel extensions. These variants include additional assertions and error checking beyond what is present in the shipping version of the macOS kernel, and may be useful for debugging in various situations. Choose the variant that best suits your needs: | |
• The kernel (release) variant matches the shipping kernel for users. | |
• The kernel.development (development) variant is safe for everyday use during development, and has minimal performance overhead. | |
• The kernel.kasan (kasan) variant enables address sanitizer features. | |
When performing two-machine debugging, install these kernel variants on the target device. | |
Note: Apple silicon Macs don’t support the kernel and kernel extension variants from the KDK. | |
Install the Variants on an Intel-Based Mac | |
To install new kernel and kernel extension variants on the target device, perform the following steps: | |
Step 1: Install the KDK | |
Install this KDK on the target device. | |
Step 2: Modify the Security Configuration of Your Mac | |
Modify the security configuration of your Mac by disabling SIP and enabling permissive security: | |
1. Reboot your system in Recovery Mode. | |
2. If your device has the Apple T2 Security Chip, set the Secure Boot policy to “Medium Security”. | |
3. Launch Terminal and run the following commands to disable System Integrity Protection (SIP) and Authenticated Root protection: | |
⁃ csrutil disable | |
⁃ csrutil authenticated-root disable | |
4. Reboot your Mac computer. | |
Step 3: Identify the System Volume Disk Device Name | |
Run the mount command in Terminal to identify the devices of your system volume snapshot. Look for the device mounted at “/“, which identifies the system volume disk. In the following example, this disk is /dev/disk4s5s1. | |
/dev/disk4s5s1 on / (apfs, sealed, local, read-only, journaled) | |
devfs on /dev (devfs, local, nobrowse) | |
/dev/disk4s4 on /System/Volumes/VM (apfs, local, noexec, journaled, noatime, nobrowse) | |
/dev/disk4s2 on /System/Volumes/Preboot (apfs, local, journaled, nobrowse) | |
/dev/disk4s1 on /System/Volumes/Data (apfs, local, journaled, nobrowse) | |
To get the actual name of the system volume disk, remove the final “sX” from the device. In the preceding example, the name of the system volume disk is /dev/disk4s5. | |
Step 4: Mount a Live Version of the System Volume | |
Run the mount command in Terminal to mount the system volume disk to a temporary location. When running the mount command, always include the nobrowse mount option to prevent Spotlight from indexing the volume. | |
mkdir /Users/jappleseed/livemount | |
sudo mount -o nobrowse -t apfs /dev/disk4s5 /Users/jappleseed/livemount | |
Step 5: Add the Variant Files to the Live Mount | |
Add the kernel variant files to the newly mounted disk. The easiest way to copy the files is to copy the entire /System directory of the KDK into the /System directory of your mounted disk, as shown in the following example: | |
sudo ditto /Library/Developer/KDKs/<KDK Version>/System /Users/jappleseed/livemount/System | |
Step 6: Rebuild the Kernel Collections and Bless the Changes | |
Run kmutil in Terminal to rebuild the kernel collections for the variants you added to your mounted disk. Run bless to authorize booting from your modified kernels. | |
sudo kmutil install --volume-root /Users/jappleseed/livemount --update-all | |
sudo bless --folder /Users/jappleseed/livemount/System/Library/CoreServices --bootefi --create-snapshot | |
Step 7: Set the boot-args | |
Run the nvram tool in Terminal to add the following key to your boot args: | |
• kcsuffix — Set the value of this key to either development or kasan, based on which kernel variant you want to use. Omit this argument if you want the release kernel. | |
For example: | |
sudo nvram boot-args=“debug=0x44 kdp_match_name=en1 wdt=-1 kcsuffix=development” | |
Step 8: Reboot the Device | |
Upon rebooting, the selected kernel variant is active. | |
Remove the Variants | |
To remove all kernel variants from your Intel-based Mac, perform a software update, either to the current version of macOS, or to a newer version. | |
Re-enable System Integrity Protection, and restore full SecureBoot security. | |
In addition, remove the boot args you were using, | |
sudo nvram -d boot-args | |
Configuring a Core Dump Server | |
You can use another Mac to capture core dumps from your system automatically over the network. This may be useful for kernel panics that occur early in the boot cycle, or when the kernel fails to write the core dump file to disk after a panic. You can use a core dump server simultaneously with two-machine debugging. Use the following terminology to refer to the Macs associated with core dumps: | |
- The target device is the Mac that generates the core dump file. | |
- The server device is the Mac that receives the core dump files. | |
Configure the Server Device | |
Step 1: Create a /PanicDumps Directory | |
Create a directory on the server, and configure it to be writable by any user. This directory is where the server stores the core dump files. | |
mkdir /Users/jappleseed/dumps chmod 1777 /Users/jappleseed/dumps | |
Edit the /etc/synthetic.conf file to create a link named /PanicDumps that can be modified by any user. | |
PanicDumps Users/jappleseed/dumps | |
For more information, see the synthetic.conf(5) man page. | |
Step 2: Reboot the Device | |
You must reboot the device before the new /PanicDumps link appears. | |
Step 3: Load the kdumpd Launch Daemon | |
Run the launchctl command in Terminal to load the kdumpd launch daemon. This service listens for incoming core dumps and writes them to /PanicDumps. | |
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.kdumpd.plist | |
Configure the Target Device | |
The same compatibility requirements apply to the target device as for two-machine debugging. You must also configure the target device as if you’re using it for two-machine debugging. | |
After performing those configuration steps, perform the following additional steps: | |
Step 1: Set additional boot-args | |
Add the following keys to your boot args: | |
• debug=0xc44—Tells the kernel to create a core dump when a panic or NMI occurs. | |
• _panicd_ip=10.0.40.2—Set the value of this key to the IP address of the server device. | |
sudo nvram boot-args=“debug=0xc44 kdp_match_name=en1 wdt=-1 _panicd_ip=10.0.40.2” | |
Step 2: Reboot the Device | |
After you reboot the target device, it sends core dumps to the server in the following situations: | |
• If the target device panics. | |
• If you trigger an NMI on the target device. | |
Core dumps can be very large, so it may take some time for the core dump to transfer over the network. | |
Finish Up | |
When you no longer want to gather core dumps from the target device, return that device to normal operation. To do that, reenable SIP and use the nvram tool to remove any boot args: | |
sudo nvram -d boot-args | |
When you no longer wish to capture core dumps on the server device, remove the PanicDumps entry from synthetic.conf and reboot the server. The reboot also stops the kdumpd launch daemon. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment