public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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 12:42:31 -0700	[thread overview]
Message-ID: <F217C205-0FDB-4114-8455-199EF71FF99E@apple.com> (raw)
In-Reply-To: <CAJQtwF3J5Ay88tHQgxQOgdUD+npfwnCr5pKyMBWxsuhFVp7sLw@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5400 bytes --]



> On Jun 11, 2021, at 11:39 AM, Ethin Probst <harlydavidsen@gmail.com> wrote:
> 
> Hi Andrew,
> How do you debug the EFI binary with LLDB? Can LLDB use GDB stubs or
> does that work differently?
> 

Ethin,

Lldb is the command line debugger that comes with Xcode on Mac. There is no gdb with Xcode, so I have to use lldb for my day job. 

Lldb can speak the gdb remote serial protocol: lldb -o “gdb-remote 9000” 
That assumes you passed `-gdb tcp::9000`to QEMU.

Thanks,

Andrew Fish

> On 6/11/21, Andrew Fish <afish@apple.com <mailto:afish@apple.com>> wrote:
>> 
>> 
>>> 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
>>> 
>>> 
>>> 
>>> 
>>> 
>> 
>> 
> 
> 
> -- 
> Signed,
> Ethin D. Probst
> 
> 
> 


[-- Attachment #2: Type: text/html, Size: 15550 bytes --]

  reply	other threads:[~2021-06-11 19:42 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 ` [edk2-devel] " Andrew Fish
2021-06-11 18:39   ` Ethin Probst
2021-06-11 19:42     ` Andrew Fish [this message]
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=F217C205-0FDB-4114-8455-199EF71FF99E@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