Skip to content

Debuging XNU with CLion

Alexander Bradley edited this page Aug 18, 2018 · 4 revisions

CLion, GDB & Qemu

macOS only for the moment.

Since we don't have a lot of fancy tools and emulators to work with, we have figured another way of debugging the xnu kernel in a familiar way. This involves the use of 3 tools, Qemu (not any qemu), CLion and GDB.

Please read this tutorial to get you started.

WARNING:

This may leave Xcode useless for iOS applications! Use with caution.

Pre requisites:

  • A version of Qemu able to boot xnu, there is one here

  • iOS 11.2.5 DeviceTree for iPhone 7 (You know where to find it).

Getting CLion to build XNU

CLion by default doesnt come with Makefile support, but it can be added with the help of a plugin.

Steps

  1. Install the Makefile plugin from Jetbrains.

  2. Go to Edit configurations... > + > Makefile.

  3. Disable Single instance only.

  4. Fill your newly created configuration with the following information:

  • Makefile: PATH_TO_XNU/Makefile
  • Arguments: -j8
  • Working directory: PATH_TO_XNU
  • Environment Variables:
Name Value
SDKROOT iphoneos or iphoneos.internal
ARCH_CONFIGS ARM64
KERNEL_CONFIGS DEBUG
BUILD_WERROR 0

Note: I created an sdk named iPhoneOS.internal, is just a copy of Xcode's iPhoneOS.sdk but with a modified Info.plist (so that I can call xcrun with iphoneos.internal) and the headers and tools described in Building XNU. This sdk seems to be able to build the debugging version of the kernel.

With all this you should be able to build xnu from CLion, just by selecting your Makefile configuration and running it.

Getting CLion to debug XNU

At this point you should be able to build the xnu kernel. Now, lets get our breakpoints working.

Note: I'm too lazy to find how to solve this, but everytime you need to restart your debug you need to close qemu (CLion won't stop it). A quick workaround is to put killall qemu-system-aarch64 one line before qemu/build-aarch64/aarch64-softmmu/qemu-system-aarch64 -M virt -cpu max \.

Steps:

  1. First we need to create a GDB Remote Debug configuration with the following:
  • target remote args: 127.0.0.1:1234
  • symbol file: <PATH TO XNU>/BUILD/obj/mach.debug
  • sysroot: <PATH TO XNU>/BUILD/obj/
  1. We would also want to build before launching the debugger, so we need to add our Makefile configuration to the Before launch section.

  2. Also, in order to make this a little easier, we would want to launch Qemu before debugging, so, in the Before launch section add an External tool with the following:

  • Program: /usr/bin/bash
  • Arguments: -c ./runqemu.sh
  • Working directory: xnuqemu_dist (read the article at the top if you don't know where this comes form)

Note: Edit ./runqemu.sh so that it uses our just compiled kernel. Add & after $@ to run in background and change -kernel kcache_out.bin for -kernel <PATH TO XNU>/BUILD/obj/mach.debug

At this point, you should be able to set breakpoints, pause the execution of xnu, etc., if you had any problems with this tutorial feel free to open an Issue.

Let's start debugging!

Clone this wiki locally