Skip to content

How to debug guest with virtualization framework

Kei Kamikawa edited this page Nov 1, 2022 · 1 revision
  1. Disable SIP (boot into recovery mode by holding the power button when booting, login your account, open the terminal, type csrutil disable, agree) (Note: doing this lowers system security, e.g. you may not be able to use google chrome or electron based apps, such as discord)
  2. Restart
  3. Open Terminal, type sudo nvram boot-args="amfi_get_out_of_my_way=1 ipc_control_port_options=0" (Note: this command lowers system security, e.g. you may not be able to use google chrome or electron based apps, such as discord)
  4. Restart
  5. Add com.apple.private.virtualization entitlement and set value as true
  6. Run codesign and go build your binary with -tags debug
  7. Enjoy your debugging
  8. After debugging, run the following command in terminal to reset your boot-args: sudo nvram boot-args=""
  9. After debugging, you should enable SIP again: run csrutil enable from recovery mode. (Note: some apps, such as Netflix, will stop working after you enable SIP, so you may have to keep SIP disabled to use specific apps, although this is not recommended)

Note: If you have problems with csrutil command (failed). Go to System Preferences, Privacy & Security, disable FileVault, enable it, and choose to allow unlock disk from iCloud option. If you have multiple macOS installations, you should set the startup disk to the macOS install that you're changing SIP for.

(This article is based on https://www.applegamingwiki.com/wiki/PlayCover#Login_Fixes)

Start debug

First, you have to add these code

debugStub, err := vz.NewGDBDebugStubConfiguration(8888)
if err != nil {
	log.Fatalf("gdb debug stub creation failed: %s", err)
}
config.SetDebugStubVirtualMachineConfiguration(debugStub)

Run the binary and start VM. Let's wake up lldb on another terminal session.

※ Hopefully someone will write more about it.

$ lldb
(lldb) gdb-remote localhost:8888
Process 1 stopped
* thread #1, name = 'CPU1', stop reason = signal SIGSTOP
    frame #0: 0xffffff80089ba014
error: memory read failed for 0xffffff80089ba000
Target 0: (No executable module.) stopped.
(lldb) bt
* thread #1, name = 'CPU1', stop reason = signal SIGSTOP
  * frame #0: 0xffffff80089ba014
    frame #1: 0xffffff80089ba044
    frame #2: 0xffffff80089c5750
    frame #3: 0xffffff80080f0fa0
    frame #4: 0xffffff80080f1244
    frame #5: 0xffffff80089ba81c
    frame #6: 0xffffff8008d116f8
    frame #7: 0xffffff8008d1250c
    frame #8: 0xffffff8008d103d0
(lldb) c
Process 1 resuming
(lldb) process status
Process 1 is running.
(lldb) process interrupt
Process 1 stopped
* thread #1, name = 'CPU1', stop reason = signal SIGSTOP
    frame #0: 0xffffff80089ba014
error: memory read failed for 0xffffff80089ba000
Target 0: (No executable module.) stopped.
(lldb) bt
* thread #1, name = 'CPU1', stop reason = signal SIGSTOP
  * frame #0: 0xffffff80089ba014
    frame #1: 0xffffff80089ba044
    frame #2: 0xffffff80089c5750
    frame #3: 0xffffff80080f0fa0
    frame #4: 0xffffff80080f1244
    frame #5: 0xffffff80089ba81c
    frame #6: 0xffffff8008d116f8
    frame #7: 0xffffff8008d1250c
    frame #8: 0xffffff8008d103d0
(lldb) ^D