From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ma1-aaemail-dr-lapp03.apple.com (ma1-aaemail-dr-lapp03.apple.com [17.171.2.72]) by mx.groups.io with SMTP id smtpd.web09.2341.1623440555006410457 for ; Fri, 11 Jun 2021 12:42:35 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@apple.com header.s=20180706 header.b=jrMkArtU; spf=pass (domain: apple.com, ip: 17.171.2.72, mailfrom: afish@apple.com) Received: from pps.filterd (ma1-aaemail-dr-lapp03.apple.com [127.0.0.1]) by ma1-aaemail-dr-lapp03.apple.com (8.16.0.42/8.16.0.42) with SMTP id 15BJXNnS022298; Fri, 11 Jun 2021 12:42:34 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apple.com; h=from : content-type : mime-version : subject : date : references : to : in-reply-to : message-id; s=20180706; bh=tZAFt8IuwD07rn2x/WE7RqarCcc3NK5rQ+5f0Q4aaa8=; b=jrMkArtUHo7D2vDQ2KvhmpvdTNVYnoLAEZXmIRqs80XTSrP2JERylI+wjZoHWwIlG2No 4jAnKpVF4e6dYccY867yxx+jEUYoMLEay3MThXEGwVsq+yWS5r+lFc/jY7uP8NXLEMPt mkce86pJuSm4VTW7jPRpE1BcgRPUAW5tWBq4U7tRx1F5L0dlybbm8ysJwDoS6bw4393i Ltn4XlcMgnbySocI2ELu2b2SxMM/zqLf/fYW6Nctg6wnsywzP7H/Lp4nJk51/QO2BKKd DTFdSK7A65ce35shAVmgO+bsD5NLNf2ZLYXoWE38AZtWGr9ALYNMpyZGGOR9VmRhHguH Gg== Received: from rn-mailsvcp-mta-lapp04.rno.apple.com (rn-mailsvcp-mta-lapp04.rno.apple.com [10.225.203.152]) by ma1-aaemail-dr-lapp03.apple.com with ESMTP id 39088yd1v5-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Fri, 11 Jun 2021 12:42:33 -0700 Received: from rn-mailsvcp-mmp-lapp04.rno.apple.com (rn-mailsvcp-mmp-lapp04.rno.apple.com [17.179.253.17]) by rn-mailsvcp-mta-lapp04.rno.apple.com (Oracle Communications Messaging Server 8.1.0.9.20210415 64bit (built Apr 15 2021)) with ESMTPS id <0QUJ003XBYQXO280@rn-mailsvcp-mta-lapp04.rno.apple.com>; Fri, 11 Jun 2021 12:42:33 -0700 (PDT) Received: from process_milters-daemon.rn-mailsvcp-mmp-lapp04.rno.apple.com by rn-mailsvcp-mmp-lapp04.rno.apple.com (Oracle Communications Messaging Server 8.1.0.9.20210415 64bit (built Apr 15 2021)) id <0QUJ00X00YO87100@rn-mailsvcp-mmp-lapp04.rno.apple.com>; Fri, 11 Jun 2021 12:42:33 -0700 (PDT) X-Va-A: X-Va-T-CD: 494ba4982f0b5c44357f821690cbd4e9 X-Va-E-CD: c087f721d3a96ee8ad637b8e41fc3a56 X-Va-R-CD: b7e321ce675588393d108a7b4559214d X-Va-CD: 0 X-Va-ID: a80b9abe-32d8-4e32-8762-fcf1a761d003 X-V-A: X-V-T-CD: 494ba4982f0b5c44357f821690cbd4e9 X-V-E-CD: c087f721d3a96ee8ad637b8e41fc3a56 X-V-R-CD: b7e321ce675588393d108a7b4559214d X-V-CD: 0 X-V-ID: 22ea636a-d5ac-43d8-861c-5d905bfeb309 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.761 definitions=2021-06-11_06:2021-06-11,2021-06-11 signatures=0 Received: from [17.235.24.70] (unknown [17.235.24.70]) by rn-mailsvcp-mmp-lapp04.rno.apple.com (Oracle Communications Messaging Server 8.1.0.9.20210415 64bit (built Apr 15 2021)) with ESMTPSA id <0QUJ005ITYQWQG00@rn-mailsvcp-mmp-lapp04.rno.apple.com>; Fri, 11 Jun 2021 12:42:32 -0700 (PDT) From: "Andrew Fish" MIME-version: 1.0 (Mac OS X Mail 14.0 \(3654.20.0.2.1\)) Subject: Re: [edk2-devel] Help with debugging Date: Fri, 11 Jun 2021 12:42:31 -0700 References: <0A1C6D8D-7F91-4038-B340-21104F14D00B@apple.com> To: edk2-devel-groups-io , Ethin Probst In-reply-to: Message-id: X-Mailer: Apple Mail (2.3654.20.0.2.1) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.761 definitions=2021-06-11_06:2021-06-11,2021-06-11 signatures=0 Content-type: multipart/alternative; boundary="Apple-Mail=_81685CF3-2C85-4FA2-9477-D4914CF18817" --Apple-Mail=_81685CF3-2C85-4FA2-9477-D4914CF18817 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Jun 11, 2021, at 11:39 AM, Ethin Probst wro= te: >=20 > Hi Andrew, > How do you debug the EFI binary with LLDB? Can LLDB use GDB stubs or > does that work differently? >=20 Ethin, Lldb is the command line debugger that comes with Xcode on Mac. There is n= o gdb with Xcode, so I have to use lldb for my day job.=20 Lldb can speak the gdb remote serial protocol: lldb -o =E2=80=9Cgdb-remote= 9000=E2=80=9D=20 That assumes you passed `-gdb tcp::9000`to QEMU. Thanks, Andrew Fish > On 6/11/21, Andrew Fish > wrote= : >>=20 >>=20 >>> On Jun 11, 2021, at 10:06 AM, Ethin Probst >>> wrote: >>>=20 >>> Hey all, >>>=20 >>> So Leif and I have discussed this at length but I thought I'd reach >>> out to all of you for more help. >>>=20 >>> I'm having a lot of trouble debugging my UEFI app. Here's how I do >>> things: >>>=20 >>> - 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=3Daudio -audiodev alsa,id=3Daudio= -s >>> -debugcon file:../debug.log -global isa-debugcon.iobase=3D0x402 >>> -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=3Daudio -audiodev alsa,id=3Daudio= -s >>> -debugcon stdio -global isa-debugcon.iobase=3D0x402 >>> - 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 >>> 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 ", I can't jump into >>> my code without triggering a general protection exception or not >>> actually causing anything to happen... You get the idea. >>>=20 >>> So I'm really, really confused on what's going wrong. Do you guys have >>> any advice? >>=20 >> Ethin, >>=20 >> Caveat emptor as I use lldb for my daily driver debugger so I might be = a >> little off on gdb specifics=E2=80=A6. Also my terminology may be lldb c= entric. >>=20 >> Easy one 1st. When you run on top of a debugger using CpuBreakpoint() w= orks >> great as the debugger hides its self from you. On x86 CpuBreakpoint() i= s an >> INT 3h instruction (0xCC) and it causes an exception 3. If you don=E2= =80=99t 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 vari= able >> with the debugger to continue. >>=20 >> I=E2=80=99d suggest a work flow of run your App/Driver, hit the CpuDead= Loop(), >> 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 conce= pt 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. >>=20 >> The EFI images are PE/COFF relocatable executables that are linked arou= nd >> zero. They get loaded into memory and relocated, so that is why you nee= d 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. T= his >> lets you poke around the image at the linked address. You can disassemb= le >> 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 th= e >> correct address, as you can see what bytes/instructions should be at a = given >> address. >>=20 >> Thanks, >>=20 >> Andrew Fish >>=20 >>>=20 >>> -- >>> Signed, >>> Ethin D. Probst >>>=20 >>>=20 >>>=20 >>>=20 >>>=20 >>=20 >>=20 >=20 >=20 > --=20 > Signed, > Ethin D. Probst >=20 >=20 >=20 --Apple-Mail=_81685CF3-2C85-4FA2-9477-D4914CF18817 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8

On Jun 11, 2= 021, at 11:39 AM, Ethin Probst <harlydavidsen@gmail.com> wrote:

<= span style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size:= 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; = letter-spacing: normal; text-align: start; text-indent: 0px; text-transform= : none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: = 0px; text-decoration: none; float: none; display: inline !important;" class= = =3D"">Hi Andrew,
How= do you debug the EFI binary with LLDB? Can LLDB use GDB stubs ordoes that work differently?


Ethin,
<= br class=3D"">
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 remot= e serial protocol: lldb -o =E2=80=9Cgdb-remote 9000=E2=80=9D 
That assumes you passed `-gdb tcp::9000`to QEMU.

Thanks,

Andrew Fish<= /div>
On 6/11/21, Andrew Fish <afish@apple.com&= gt; 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.c= om/Richard-W/uefi-run) like this (from the main EDK
II di= rectory): uefi-run -b Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd
Bui= ld/OvmfX64/DEBUG_GCC5/X64/Shell.efi -- -M q35 -m 24G -usb -device
qemu-xhci -device usb-audio,audiodev=3Daudio -audiodev alsa,id=3Daud= io -s
-debugcon file:../debug.log -global isa-debugcon.iobase= = =3D0x402
-nographic
Or:
uefi-run= -b Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd
Build/OvmfX64/DEBUG_G= CC5/X64/Shell.efi -- -M q35 -m 24G -usb -device
qemu-xhci -de= vice usb-audio,audiodev=3Daudio -audiodev alsa,id=3Daudio -s
= -debugcon stdio -global isa-debugcon.iobase=3D0x402
- I conne= ct to the remote GDB stub (localhost:1234) and wait until
OVM= F gives me the image base. Then I use:
add-symbol-file UsbAud= io.debug <image base>
Here's where everything breaks do= wn. 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; or2. If I use CpuBreakpoint(), the firmware gives me the registe= rs and
the image base and entry point addresses, and then app= ears to just sit
there waiting for something. Once I load the= symbols using the image
base it gives me, I can't actually d= o anything in the debugger; I
can't list code because I get "= 1 in <artificial>", I can't jump into
my code without t= riggering a general protection exception or not
actually caus= ing 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 debu= gger so I might be a
little off on gdb specifics=E2=80=A6. Al= so my terminology may be lldb centric.

Easy on= e 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=E2=80=99t have a
debugger hooked in underneath=  the exception 3 is going to get handled in
the unexpec= ted exception handler, and that is probably in the CPUD DXE
d= river 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 fr= om QEMU acts a lot
more like a JTAG hardware debugger than a = pure software debugger. Also note
that CpuDeadLoop() is an in= finite loop, so you can modify the loop variable
with the deb= ugger to continue.

I=E2=80=99d suggest a work = flow of run your App/Driver, hit the CpuDeadLoop(),
attach gd= b. Now after you have the target established load the symbols. The
reason for me suggesting this flow is the debugger has a flexible co= ncept of
what the target is. If you load symbols that will cr= eate a target for a
stock x86-64 image. When you connect to t= he QEMU gdb-remote there is a
handshake that describes the ta= rget and what registers are available. I seem
to remember QEM= U exports some of the system registers, like the control
regi= sters, so it is an extended version of the x86-64 target. So this
changing the target definition might confuse the debugger. To be saf= e I
always connect 1st and then load symbols.
<= br class=3D"">The EFI images are PE/COFF relocatable executables that are l= inked around
zero. They get loaded into memory and relocated,= so that is why you need to
specify the load address to get t= he 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 an= y
variables. This can be useful if you get the unhandled exce= ption 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
addr= ess.

Thanks,

Andr= ew Fish

<= br class=3D"">--
Signed,
Ethin D. Probst









-- 
Signed,
Ethin D. Probst



--Apple-Mail=_81685CF3-2C85-4FA2-9477-D4914CF18817--