-
Notifications
You must be signed in to change notification settings - Fork 891
Guest debugging support #66
Description
Opening this issue as follow-up to the discussion in qemu-devel:
https://lists.gnu.org/archive/html/qemu-devel/2018-04/msg00030.html
Summarizing: Guest debugging is extremely relevant to debugging bootloaders/microkernels, or in my case, kernels that do not include debugging backends. Aside from the intrinsic value of this feature, it's also really beneficial to developers/researchers as neither WHPX (Windows) nor HVF (macOS) support guest debugging and while they remain closed-source this probably won't change.
This week I've started experimenting with guest debugging support on HAXM, but it's still too early to submit any patches (plus, this should probably coordinated with QEMU somehow). These are the key ideas (inspired by KVM):
- Adding a
HAX_VCPU_IOCTL_DEBUGioctl (i.e. QEMU-to-HAXM) with a structure containing:- Flags to enable/disable debugging and specific features:
This is meant to manage the guest state accordingly: e.g. if guest debugging via hardware breakpoints is enabled we should protect the guest drN values in theexit_dr_accesshandler. Additionally, to know where to redirect #BP, e.g. if software breakpoints are enabled forward to QEMU, otherwise forward to VM. - Values for debugging registers: dr0, dr1, dr2, dr3, dr6, dr7:
They already are a self-contained way of describing hardware breakpoints, so no need to wrap that information in another layer of abstraction.
- Flags to enable/disable debugging and specific features:
- Adding a
HAX_EXIT_DEBUGexit (i.e. HAXM-to-QEMU) with a structure containing:- Cause: Software breakpoint, hardware breakpoint, singlestep.
- Value of: rip: For software breakpoint events.
- Value of: dr6, dr7: For hardware breakpoint events.
- Software breakpoints are managed by QEMU as an array of objects containing an address and the original byte at that instruction before patching
int 3h(0xCC). Its lifecycle is:- GDB: Sends
break *command. - QEMU: Creates/initializes
hax_sw_brakpointobject and patches instruction withint 3h. - HAXM: Runs the virtual machine, and returns to QEMU after hitting
#BP. - QEMU: Returns control to GDB.
- GDB: Sends
continuecommand. - QEMU: Reverts the instruction patch and single-steps.
- HAXM: Executes one instruction and returns.
- QEMU: Reapplies the instruction patch and resumes execution.
- GDB: Sends
- Hardware breakpoints are specified by directly writing into the guest
drNregister through the previously described ioctl.
Current experiments can be found in AlexAltea/orbital-qemu@77d61c7 (QEMU) and https://github.com/AlexAltea/haxm/tree/debug (HAXM). I'm facing some issues still:
- Hardware breakpoints have no effect.
- Software breakpoints trigger a triple fault, not a
#BP.
Disclaimer: I haven't much experience with debuggers, so any feedback will be helpful.