From: "Andrew Fish" <afish@apple.com>
To: edk2-devel-groups-io <devel@edk2.groups.io>,
Ethin Probst <harlydavidsen@gmail.com>
Subject: Re: [edk2-devel] Help with debugging
Date: Fri, 11 Jun 2021 11:23:10 -0700 [thread overview]
Message-ID: <0A1C6D8D-7F91-4038-B340-21104F14D00B@apple.com> (raw)
In-Reply-To: <CAJQtwF2aoF8qO2LB7pa76L2Pz8OTfMPVzuj8y_iA9afM1J2ySA@mail.gmail.com>
> On Jun 11, 2021, at 10:06 AM, Ethin Probst <harlydavidsen@gmail.com> wrote:
>
> Hey all,
>
> So Leif and I have discussed this at length but I thought I'd reach
> out to all of you for more help.
>
> I'm having a lot of trouble debugging my UEFI app. Here's how I do things:
>
> - I load the app using uefi-run
> (https://github.com/Richard-W/uefi-run) like this (from the main EDK
> II directory): uefi-run -b Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd
> Build/OvmfX64/DEBUG_GCC5/X64/Shell.efi -- -M q35 -m 24G -usb -device
> qemu-xhci -device usb-audio,audiodev=audio -audiodev alsa,id=audio -s
> -debugcon file:../debug.log -global isa-debugcon.iobase=0x402
> -nographic
> Or:
> uefi-run -b Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd
> Build/OvmfX64/DEBUG_GCC5/X64/Shell.efi -- -M q35 -m 24G -usb -device
> qemu-xhci -device usb-audio,audiodev=audio -audiodev alsa,id=audio -s
> -debugcon stdio -global isa-debugcon.iobase=0x402
> - I connect to the remote GDB stub (localhost:1234) and wait until
> OVMF gives me the image base. Then I use:
> add-symbol-file UsbAudio.debug <image base>
> Here's where everything breaks down. One of two things happens at this point:
> 1. Either I get the wrong debug information (I get source code but the
> image isn't loaded anymore), and resetting the system and placing a
> breakpoint (either software or hardware) has no effect; or
> 2. If I use CpuBreakpoint(), the firmware gives me the registers and
> the image base and entry point addresses, and then appears to just sit
> there waiting for something. Once I load the symbols using the image
> base it gives me, I can't actually do anything in the debugger; I
> can't list code because I get "1 in <artificial>", I can't jump into
> my code without triggering a general protection exception or not
> actually causing anything to happen... You get the idea.
>
> So I'm really, really confused on what's going wrong. Do you guys have
> any advice?
Ethin,
Caveat emptor as I use lldb for my daily driver debugger so I might be a little off on gdb specifics…. Also my terminology may be lldb centric.
Easy one 1st. When you run on top of a debugger using CpuBreakpoint() works great as the debugger hides its self from you. On x86 CpuBreakpoint() is an INT 3h instruction (0xCC) and it causes an exception 3. If you don’t have a debugger hooked in underneath the exception 3 is going to get handled in the unexpected exception handler, and that is probably in the CPUD DXE driver or DXE Core or some such. So you are going to end up with the PC/IP/RIP in the wrong driver. A lot of times for hardware debuggers it works better to use CpuDeadLoop(). The gdb-remote stub from QEMU acts a lot more like a JTAG hardware debugger than a pure software debugger. Also note that CpuDeadLoop() is an infinite loop, so you can modify the loop variable with the debugger to continue.
I’d suggest a work flow of run your App/Driver, hit the CpuDeadLoop(), attach gdb. Now after you have the target established load the symbols. The reason for me suggesting this flow is the debugger has a flexible concept of what the target is. If you load symbols that will create a target for a stock x86-64 image. When you connect to the QEMU gdb-remote there is a handshake that describes the target and what registers are available. I seem to remember QEMU exports some of the system registers, like the control registers, so it is an extended version of the x86-64 target. So this changing the target definition might confuse the debugger. To be safe I always connect 1st and then load symbols.
The EFI images are PE/COFF relocatable executables that are linked around zero. They get loaded into memory and relocated, so that is why you need to specify the load address to get the symbols to resolve. One trick I use is to load the ELF (or PE/COFF) build output directly into the debugger. This lets you poke around the image at the linked address. You can disassemble the functions to see what they look like, obviously you can read any variables. This can be useful if you get the unhandled exception and it prints out the load address and offset (you can use the offset directly). It is also a good way to debug why your symbols are not quite loaded at the correct address, as you can see what bytes/instructions should be at a given address.
Thanks,
Andrew Fish
>
> --
> Signed,
> Ethin D. Probst
>
>
>
>
>
next prev parent reply other threads:[~2021-06-11 18:23 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-11 17:06 Help with debugging Ethin Probst
2021-06-11 18:23 ` Andrew Fish [this message]
2021-06-11 18:39 ` [edk2-devel] " Ethin Probst
2021-06-11 19:42 ` Andrew Fish
2021-06-11 20:48 ` Ethin Probst
2021-06-11 20:58 ` Andrew Fish
2021-06-11 21:29 ` Ethin Probst
2021-06-11 23:09 ` Andrew Fish
2021-06-11 23:29 ` Ethin Probst
2021-06-11 23:48 ` Andrew Fish
2021-06-12 4:47 ` Ethin Probst
2021-06-12 19:03 ` Andrew Fish
2021-06-23 11:39 ` Laszlo Ersek
2021-06-23 17:20 ` Ethin Probst
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0A1C6D8D-7F91-4038-B340-21104F14D00B@apple.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox