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.web11.17533.1584824769418249475 for ; Sat, 21 Mar 2020 14:06:10 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@apple.com header.s=20180706 header.b=PUp+oJ9s; 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.27/8.16.0.27) with SMTP id 02LL2BiC010094; Sat, 21 Mar 2020 14:06:07 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apple.com; h=sender : from : message-id : content-type : mime-version : subject : date : in-reply-to : cc : to : references; s=20180706; bh=yKHSgSXYZaIEBsyvjiJx4JzU1Zqe6B5kE6M9BrEgRsk=; b=PUp+oJ9sqBjMWL3HgtfsBWmBDgSaijoox0SRn/83h5xStwjLPqwYxSpwDlbPAGJNansI lGsRXSLBWNYcsYonHB13wBw98MPLEkdrmWl26sEo1Hwsoy9RK2NP0OdwirAM4BPZw3fx ZToOJeWGcfwCc9SZjpw/ZuiOFxSCmaAQZcRdcZxUhH9oBDU3kjTkotCdLirNiaGLnPfa IBUaVRcKfWrwj0JkAGujJN7GCd0G92zF16BRPTFvQsEn49BaIvgQoefPFNrZA5Vww8s1 pwj8OXeK28gK5l/NRoUv6BzumP8xqaj/HIj1hHoESrLIg1mnvje7sP7LNcOY2p+jYRD5 nQ== Received: from rn-mailsvcp-mta-lapp02.rno.apple.com (rn-mailsvcp-mta-lapp02.rno.apple.com [10.225.203.150]) by ma1-aaemail-dr-lapp03.apple.com with ESMTP id 2ywhwyy1h9-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Sat, 21 Mar 2020 14:06:07 -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-lapp02.rno.apple.com (Oracle Communications Messaging Server 8.1.0.5.20200312 64bit (built Mar 12 2020)) with ESMTPS id <0Q7K00DEDAM6G240@rn-mailsvcp-mta-lapp02.rno.apple.com>; Sat, 21 Mar 2020 14:06:06 -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.5.20200312 64bit (built Mar 12 2020)) id <0Q7K00W009O3HR00@rn-mailsvcp-mmp-lapp04.rno.apple.com>; Sat, 21 Mar 2020 14:06:06 -0700 (PDT) X-Va-A: X-Va-T-CD: 2c323b19c9bf43c24bf8f3f2bb9cbf14 X-Va-E-CD: 36a32cfa42a5ae8aa02473601c03cec7 X-Va-R-CD: d2d46cdd9ed31419d4eb89636f43916d X-Va-CD: 0 X-Va-ID: 503d4f32-cbd8-4dc7-8415-3513d6bf97f7 X-V-A: X-V-T-CD: 2c323b19c9bf43c24bf8f3f2bb9cbf14 X-V-E-CD: 36a32cfa42a5ae8aa02473601c03cec7 X-V-R-CD: d2d46cdd9ed31419d4eb89636f43916d X-V-CD: 0 X-V-ID: 687540b0-297e-48cc-976e-f6b03f89317d X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.645 definitions=2020-03-21_09:2020-03-20,2020-03-21 signatures=0 Received: from [17.235.1.56] by rn-mailsvcp-mmp-lapp04.rno.apple.com (Oracle Communications Messaging Server 8.1.0.5.20200312 64bit (built Mar 12 2020)) with ESMTPSA id <0Q7K001F3AM3ZQ50@rn-mailsvcp-mmp-lapp04.rno.apple.com>; Sat, 21 Mar 2020 14:06:05 -0700 (PDT) Sender: afish@apple.com From: "Andrew Fish" Message-id: MIME-version: 1.0 (Mac OS X Mail 13.0 \(3594.4.17\)) Subject: Re: [edk2-devel] CLANGPDB binary debugging Date: Sat, 21 Mar 2020 14:06:03 -0700 In-reply-to: <5C8DD065-0140-428B-A146-999A5694BC99@ispras.ru> Cc: "Gao, Liming" , =?utf-8?Q?Marvin_H=C3=A4user?= To: devel@edk2.groups.io, cheptsov@ispras.ru References: <9804C565-0C9E-4778-92A7-06EA6AD8D694@ispras.ru> <7E18AD8F-9A44-45FE-A8C8-CE06A6328930@apple.com> <63396616-D8CF-4135-B967-772C1E6136BD@apple.com> <5C8DD065-0140-428B-A146-999A5694BC99@ispras.ru> X-Mailer: Apple Mail (2.3594.4.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.645 definitions=2020-03-21_09:2020-03-20,2020-03-21 signatures=0 Content-type: multipart/alternative; boundary="Apple-Mail=_512E4AC5-7B40-438E-B895-B27522CB28B2" --Apple-Mail=_512E4AC5-7B40-438E-B895-B27522CB28B2 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Mar 21, 2020, at 11:36 AM, Vitaly Cheptsov wrote= : >=20 > Andrew, >=20 > Thanks once again, but unfortunately it is not that simple. Below I answ= ered inline explaining the particular issues, which mostly seem to be speci= fic to CLANGPDB. LLVM stack emits PDB debug files, and even though LLDB doe= s support them to some level, it is unlikely that this will be working well= enough soon. We should really stick to more or less native debug formats, = ideally those that have proper open specifications, on all platforms, and f= or Unix that=E2=80=99s DWARF. >=20 Vitaly, I understand and I use the Xcode clang and not the CLANGPDB, but I use lld= b a lot I was just trying to point out what works with Xcode.=20 > I am pretty sure LLVM can be taught to emit DWARF debug information even= for PE files. Perhaps we can either make some option or provide a separate= toolchain for this? Another way would be recovering CLANGELF as originally= suggested. >=20 There was a bug recently in the x86_64-pc-win32-macho triple and we had t= o add -gdwarf to force it emit dwarf. Not sure what that compiler flag woul= d do to CLANGPDB but it is worth a try? Last flag wins for the compiler.=20 >> You can teach lldb about types. There is some example code here: https:= //github.com/tianocore/edk2/blob/master/EmulatorPkg/Unix/lldbefi.py > This code works just fine with LLDB and DWARF (e.g. XCODE5), though I ha= ve not yet completed these changes for my scripts for LLDB, only for GDB. H= owever, with CLANGPDB generated files it is not functional. The reason for = this is because LLDB is unaware of the underlying type, i.e. it does not kn= ow what is EFI_STATUS or UINT32. I can implement pretty-printing when LLDB = knows about a typedef, but it is not possible to do this when the debug inf= ormation is already gone or not parsed: >=20 > (lldb) p Status > (unsigned long long) $1 =3D 0 > (lldb) p &Status > (unsigned long long *) $2 =3D 0x000000007fe19ad8 > (lldb) p (EFI_STATUS)Status > error: use of undeclared identifier 'EFI_STATUS' >=20 > Just in case I tried using exactly your code, and other stuff like sourc= e level debugging works just fine and symbolication works fine, so it shoul= d be some bug with PDB in particular. >=20 >> That is strange as globals usually work best? The common issue I've see= n is getting the slide wrong. The EFI modules are linked at a value near ze= ro and relocated into memory, so the slide represents that adjustment.=20 >>=20 >> You can use `image dump sections` and ` image dump symtab` to see lldb'= s view of symbols. More info here [1].=20 >=20 > Yes, this one is a bit complicated, once again due to PDB most likely. I= t knows about global symbols, but does not list them in symtab: >=20 > (lldb) image dump symtab > Dumping symbol table for 91 modules. > Symtab, file =3D GdbSyms/Bin/X64_CLANGPDB/GdbSyms.dll, num_symbols =3D 0 > Symtab, file =3D /Users/user/Documents/UefiWorkspace/Build/OvmfX64/NOOPT= _CLANGPDB/X64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll, num_symbols = = =3D 0 > Symtab, file =3D /Users/user/Documents/UefiWorkspace/Build/OvmfX64/NOOPT= _CLANGPDB/X64/MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe/DEBUG/Devi= cePathDxe.dll, num_symbols =3D 0 > =E2=80=A6 >=20 > The slides are correct, but there are two nuances that collide with it. >=20 > 1. There are multiple instances of the globals with the same name (e.g. = gBS), but for some reason LLDB always tries to print the globals from the f= irst module. This happens even when I am source-level debugging, and I see = a gBS symbol from another module (e.g. DxeCore) used right at the same line= . With GDB the closest symbol is used, but with LLDB it is always coming fr= om the first module. I tried checking expr help to find whether I can pass = it a module explicitly, but also failed. >=20 Usually what happens with lldb is you get the global that is in scope for = the current frame.=20 > 2. To be able to get EFI types to locate the EFI_SYSTEM_TABLE_POINTER I= add a dummy GdbSyms image, which is not loaded to the firmware. So basical= ly I cannot slide what is not in the memory, and this is also my first imag= e. I tried deleting it anyhow, but it failed for me. >=20 I've not used the fake image to get things done so I can't speak to that. = I have used a fake target so I could have XIP PEIM and shadowed PEIM addres= s available at the same time. You can't have a module loaded at 2 addresses= at the same time in llldb. But you might be able to use a fake target for = your fake stuff? Just in case: # create a faka target to store info about symbols PeiXipTarget =3D target.debugger.CreateTarget (None, "i386-apple= -macosx", "remote-macosx", True, error) # make sure the gdb-remote connection target is the active targ= et target.debugger.SetSelectedTarget (target) > (lldb) image dump sections > Dumping sections for 91 modules. > Sections for 'GdbSyms/Bin/X64_CLANGPDB/GdbSyms.dll' (x86_64): > SectID Type Load Address P= erm File Off. File Size Flags Section Name > ---------- ---------------- --------------------------------------- -= --- ---------- ---------- ---------- ---------------------------- > 0xffffffffffffffff container [0x0000000000000000-0x000000000000= 6ec0)* --- 0x00000000 0x00000000 0x00000000 GdbSyms.dll. > 0x00000001 code [0x0000000000000220-0x0000000000005bd6)* -= -- 0x00000220 0x000059c0 0x60000020 GdbSyms.dll...text > 0x00000002 data [0x0000000000005be0-0x0000000000006d79)* -= -- 0x00005be0 0x000011a0 0x40000040 GdbSyms.dll...rdata > 0x00000003 data [0x0000000000006d80-0x0000000000006e30)* -= -- 0x00006d80 0x00000060 0xc0000040 GdbSyms.dll...data > 0x00000004 regular [0x0000000000006e40-0x0000000000006ea4)* -= -- 0x00006de0 0x00000080 0x42000040 GdbSyms.dll...reloc > Sections for '/Users/user/Documents/UefiWorkspace/Build/OvmfX64/NOOPT_CL= ANGPDB/X64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll' (x86_64): > SectID Type Load Address P= erm File Off. File Size Flags Section Name > ---------- ---------------- --------------------------------------- -= --- ---------- ---------- ---------- ---------------------------- > 0xffffffffffffffff container [0x0000000000000000-0x000000000005= 23a0)* --- 0x00000000 0x00000000 0x00000000 DxeCore.dll. > 0x00000001 code [0x000000007fe1b220-0x000000007fe61e34) -= -- 0x00000220 0x00046c20 0x60000020 DxeCore.dll...text > 0x00000002 data [0x000000007fe61e40-0x000000007fe68065) -= -- 0x00046e40 0x00006240 0x40000040 DxeCore.dll...rdata > 0x00000003 data [0x000000007fe68080-0x000000007fe6d160) -= -- 0x0004d080 0x000018a0 0xc0000040 DxeCore.dll...data > 0x00000004 regular [0x000000007fe6d160-0x000000007fe6d398) -= -- 0x0004e920 0x00000240 0x42000040 DxeCore.dll...reloc > Sections for '/Users/user/Documents/UefiWorkspace/Build/OvmfX64/NOOPT_CL= ANGPDB/X64/MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe/DEBUG/DeviceP= athDxe.dll' (x86_64): > SectID Type Load Address P= erm File Off. File Size Flags Section Name > ---------- ---------------- --------------------------------------- -= --- ---------- ---------- ---------- ---------------------------- > 0xffffffffffffffff container [0x0000000000000000-0x000000000001= 4420)* --- 0x00000000 0x00000000 0x00000000 DevicePathDxe.dll. > 0x00000001 code [0x000000007f986220-0x000000007f996cc6) -= -- 0x00000220 0x00010ac0 0x60000020 DevicePathDxe.dll...text > 0x00000002 data [0x000000007f996ce0-0x000000007f999b04) -= -- 0x00010ce0 0x00002e40 0x40000040 DevicePathDxe.dll...rdata > 0x00000003 data [0x000000007f999b20-0x000000007f99a1a2) -= -- 0x00013b20 0x00000660 0xc0000040 DevicePathDxe.dll...data > 0x00000004 regular [0x000000007f99a1c0-0x000000007f99a404) -= -- 0x00014180 0x00000260 0x42000040 DevicePathDxe.dll=E2=80=A6reloc > =E2=80=A6 >=20 > So, all in all, unique global variables work, but there is no way to acc= ess duplicating variables. They either resolve to GdbSyms or just cause a c= rash: >=20 > (lldb) p mDebugInfoTableHeader > (EFI_DEBUG_IMAGE_INFO_TABLE_HEADER) $0 =3D { > UpdateStatus =3D 2 > TableSize =3D 92 > EfiDebugImageInfoTable =3D 0x000000007f814018 > } > (lldb) p gBS > error: Couldn't materialize: couldn't get the value of variable ::gBS: r= ead memory from 0x6df8 failed > error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression > (lldb) p gEfiGlobalVariableGuid > 0 libLLVM.dylib 0x000000010e52ee68 llvm::sys::PrintStackTrac= e(llvm::raw_ostream&) + 40 > 1 libLLVM.dylib 0x000000010e52f262 SignalHandler(int) + 188 > 2 libsystem_platform.dylib 0x00007fff6ca5642d _sigtramp + 29 > ... >=20 If you want to inspect globals I think this logic works to get you data, y= ou would need to print it out etc.=20 SBValueList =3D lldb.target.FindGlobalVariables ("gST", 1024) for SBValue in SBValueList: Module =3D SBValue.GetAddress().GetModule()=20 ModuleStr =3D SBValue.GetAddress().GetModule().GetFileSpec().GetFi= lename() Start =3D int (SBValue.GetLocation(), 0) End =3D Start + SBValue.GetByteSize() - 1 SBDeclaration =3D SBValue.GetDeclaration() Column =3D SBDeclaration.GetColumn() I wrote a command in the early days to dump out all the instances of a glo= bal.=20 You can also try (lldb) image lookup -Av --name gST >> You can tell lldb to use the older Python like this (from the Terminal.= app): >> $ defaults write com.apple.dt.lldb DefaultPythonVersion 2 >=20 > Thanks, that helped quite a bit, but for some reason Xcode version still= crashes more for me. I attached a couple of stack traces if you feel like = having a look, but once again it seems that it is all about the PDB plugin. >=20 >> For the macOS API clang emits frame pointers, so you can walk the stack= without symbols. You could try adding the compiler flag to emit the frame = pointers.=20 >=20 This is easy enough to check as %rpb is the frame pointer so it will get s= aved/restored on function entry/exit.=20 > I am pretty sure stack frames are not disabled with UEFI, as sometimes b= acktracing works just fine. To me it looks like debug information parsing r= andomly breaks in LLDB, and once it happens it forgets about other images: >=20 > (lldb) b CoreLocateHandleBuffer > Breakpoint 2: where =3D DxeCore.dll`CoreLocateHandleBuffer + 31 at Locat= e.c:649, address =3D 0x000000007fe36e4f > (lldb) c > Process 1 resuming > Process 1 stopped > * thread #1, stop reason =3D breakpoint 2.1 > frame #0: 0x000000007fe36e4f DxeCore.dll`CoreLocateHandleBuffer(Sear= chType=3DByProtocol, Protocol=3D0x000000007f978160, SearchKey=3D0x000000000= 0000000, NumberHandles=3D0x000000007fe19fd8, Buffer=3D0x000000007fe19fc0) a= t Locate.c:649 > 646 =09 EFI_STATUS Status; > 647 =09 UINTN BufferSize; > 648 =09 > -> 649 =09 if (NumberHandles =3D=3D NULL) { > 650 =09 return EFI_INVALID_PARAMETER; > 651 =09 } > 652 =09 > (lldb) bt > * thread #1, stop reason =3D breakpoint 2.1 > * frame #0: 0x000000007fe36e4f DxeCore.dll`CoreLocateHandleBuffer(Sear= chType=3DByProtocol, Protocol=3D0x000000007f978160, SearchKey=3D0x000000000= 0000000, NumberHandles=3D0x000000007fe19fd8, Buffer=3D0x000000007fe19fc0) a= t Locate.c:649 > frame #1: 0x000000007fe36816 DxeCore.dll`CoreLocateDevicePath(Protoc= ol=3D0x000000007f978160, DevicePath=3D0x000000007fe1a060, Device=3D0x000000= 007fe1a068) at Locate.c:466 > frame #2: 0x000000007f97479a SecurityStubDxe.dll >=20 > =E2=80=94=E2=80=94=E2=80=94 >=20 > (lldb) b CopyMem > Breakpoint 3: 70 locations. > (lldb) c > Process 1 resuming > Process 1 stopped > * thread #1, stop reason =3D breakpoint 2.53 3.53 > frame #0: 0x000000007e5c13b3 MnpDxe.dll`CopyMem(DestinationBuffer=3D= 0x000000007fe19b50, SourceBuffer=3D0x000000007e2aa470, Length=3D656) at Cop= yMemWrapper.c:47 > 44 IN UINTN Length > 45 ) > 46 { > -> 47 if (Length =3D=3D 0) { > 48 return DestinationBuffer; > 49 } > 50 ASSERT ((Length - 1) <=3D (MAX_ADDRESS - (UINTN)DestinationBuf= fer)); > (lldb) bt > * thread #1, stop reason =3D breakpoint 2.53 3.53 > * frame #0: 0x000000007e5c13b3 MnpDxe.dll`CopyMem(DestinationBuffer=3D= 0x000000007fe19b50, SourceBuffer=3D0x000000007e2aa470, Length=3D656) at Cop= yMemWrapper.c:47 > (lldb) finish > error: Could not create return address breakpoint. > (lldb) n > Process 1 stopped > * thread #1, stop reason =3D step over > frame #0: 0x000000007e5c13ce MnpDxe.dll`CopyMem(DestinationBuffer=3D= 0x000000007fe19b50, SourceBuffer=3D0x000000007e2aa470, Length=3D656) at Cop= yMemWrapper.c:50 > 47 if (Length =3D=3D 0) { > 48 return DestinationBuffer; > 49 } > -> 50 ASSERT ((Length - 1) <=3D (MAX_ADDRESS - (UINTN)DestinationBuf= fer)); > 51 ASSERT ((Length - 1) <=3D (MAX_ADDRESS - (UINTN)SourceBuffer))= ; > 52 =09 > 53 if (DestinationBuffer =3D=3D SourceBuffer) { > (lldb) > ... > Process 1 stopped > * thread #1, stop reason =3D step over > frame #0: 0x000000007e5c14b4 MnpDxe.dll`CopyMem(DestinationBuffer=3D= 0x000000007fe19b50, SourceBuffer=3D0x000000007e2aa470, Length=3D656) at Cop= yMemWrapper.c:57 > 54 return DestinationBuffer; > 55 } > 56 return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Le= ngth); > -> 57 } > (lldb) > Process 1 stopped > * thread #1, stop reason =3D step over > frame #0: 0x000000007e5c726e MnpDxe.dll > -> 0x7e5c726e: mov rax, qword ptr [rsp + 0x60] > 0x7e5c7273: cmp byte ptr [rax + 0x68], 0x0 > 0x7e5c7277: jne 0x7e5c7291 > 0x7e5c727d: movabs rax, -0x7fffffffffffffed > (lldb) bt > * thread #1, stop reason =3D step over > * frame #0: 0x000000007e5c726e MnpDxe.dll=20 >=20 > =E2=80=94=E2=80=94=E2=80=94 >=20 > (lldb) c > Process 1 resuming > Process 1 stopped > * thread #1, stop reason =3D signal SIGINT > frame #0: 0x000000007fe4d72e DxeCore.dll > -> 0x7fe4d72e: cmp al, 0x0 > 0x7fe4d730: je 0x7fe4d765 > 0x7fe4d736: mov rcx, qword ptr [rsp + 0x20] > 0x7fe4d73b: call 0x7fe4c4b0 > (lldb) bt > * thread #1, stop reason =3D signal SIGINT > * frame #0: 0x000000007fe4d72e DxeCore.dll >=20 >> On macOS the Mach-O and dSYM have a UUID (dwarfdump -u) that is indexed= by Spotlight (mdfind "com_apple_xcode_dsym_uuids =3D=3D *") [2] >> This should be the UUID in the debug directory entry and you can use th= at to lookup the symbols like this: >>=20 >> module =3D target.AddModule (None, None, uuid) >> SBError =3D target.SetModuleLoadAddress (module, LoadAddress + TeAdjust= ) >>=20 >> Also lldb has built in help for commands, but it is kind of terse since= it is autogenerated from the C++ swig.=20 >> (lldb) script help (lldb.target.AddModule) >> Help on method AddModule in module lldb: >>=20 >> AddModule(self, *args) method of lldb.SBTarget instance >> AddModule(SBTarget self, SBModule module) -> bool >> AddModule(SBTarget self, char const * path, char const * triple, ch= ar const * uuid) -> SBModule >> AddModule(SBTarget self, char const * path, char const * triple, ch= ar const * uuid_cstr, char const * symfile) -> SBModule >> AddModule(SBTarget self, SBModuleSpec module_spec) -> SBModule >>=20 >> The minimum you need to symbolicate a frame is uuid, LoadAddress, and = PC.=20 >>=20 >> [1] http://lldb.llvm.org/use/map.html >> [2] http://lldb.llvm.org/use/symbols.html > Thanks for the links again. Yes, I am using some of these, and in fact f= or GDB that=E2=80=99s pretty much what I did when I worked with XCODE5. It = is very likely that when I get to complete LLDB support for XCODE5 it will = work quite fine too. But I am already happy with XCODE5 here, and making it= even better will only help myself, but not other people with e.g. Linux or= people that want me to use the same compiler with them. >=20 Thanks for looking out for others.=20 Thanks, Andrew Fish > Best regards, > Vitaly >=20 >=20 >> 21 =D0=BC=D0=B0=D1=80=D1=82=D0=B0 2020 =D0=B3., =D0=B2 20:13, Andrew Fi= sh > =D0=BD=D0=B0=D0=BF=D0=B8=D1= =81=D0=B0=D0=BB(=D0=B0): >>=20 >>=20 >>=20 >>> On Mar 21, 2020, at 3:28 AM, Vitaly Cheptsov > wrote: >>>=20 >>> Hello, >>>=20 >>> Andrey, thanks for the hint, it was very helpful. I rewrote the GDB sc= ripts to work with LLDB[1] and was able to debug OVMF built with CLANGPDB. = While it is still quite dirty, at the very least it works. >>>=20 >>> Unfortunately the experience was close to terrible. I may certainly do= something wrong, but it is clear that PDB and LLDB do not support each oth= er well enough. After spending several hours on playing with the tools my c= onclusion is that LLDB is simply not suited for UEFI PDB debugging, and we = really want DWARF as there is no other opensource debugger that supports P= DB on macOS and Linux >>>=20 >>> In case somebody knows workarounds here are the issues I faced: >>>=20 >>> 1. All integer alias typedefs are discarded in favour of underlying ty= pes. This way EFI_STATUS and EFI_TPL become unsigned long long, CHAR8 becom= es char, and CHAR16 becomes unsigned short. It does not look like LLDB has = the original types anywhere at all, and it also does not have them register= ed. >>>=20 >>> frame #0: 0x000000007fe242aa DxeCore.dll`CoreAllocatePoolPagesI(Po= olType=3DEfiBootServicesData, NoPages=3D1, Granularity=3D4096, NeedGuard=3D= '\0') at Pool.c:322 >>> 319 =09 return NULL; >>> 320 =09 } >>> 321 =09 >>> -> 322 =09 Buffer =3D CoreAllocatePoolPages (PoolType, NoPages, Granu= larity, NeedGuard); >>> 323 =09 CoreReleaseMemoryLock (); >>> 324 =09 >>> 325 =09 if (Buffer !=3D NULL) { >>> (lldb) p Status >>> (unsigned long long) $3 =3D 0 >>>=20 >>> Structures work more or less fine, but for simpler types like strings = we are out of even potential pretty-printing. >>>=20 >>=20 >> Vitaly, >>=20 >> You can teach lldb about types. There is some example code here: https:= //github.com/tianocore/edk2/blob/master/EmulatorPkg/Unix/lldbefi.py >>> 2. Global variables are not accessible. I am not sure what happens, bu= t they either seem to not relocate or conflict with the other names: >>>=20 >>> (lldb) p gST >>> error: Couldn't materialize: couldn't get the value of variable ::gST:= read memory from 0x6e18 failed >>> error: errored out in DoExecute, couldn't PrepareToExecuteJITExpressio= n >>> (lldb) p &gST >>> error: Couldn't materialize: couldn't get the value of variable ::gST:= read memory from 0x6e18 failed >>> error: errored out in DoExecute, couldn't PrepareToExecuteJITExpressio= n >>>=20 >>=20 >> That is strange as globals usually work best? The common issue I've see= n is getting the slide wrong. The EFI modules are linked at a value near ze= ro and relocated into memory, so the slide represents that adjustment.=20 >>=20 >> You can use `image dump sections` and ` image dump symtab` to see lldb'= s view of symbols. More info here [1].=20 >>=20 >>> 3. Quite a number of crashes. >>>=20 >>> In most cases autocompletion by tab press causes a crash. E.g. >>>=20 >>> b I >>>=20 >>> So will do printing of a GUID, e.g. p gEfiGlobalVariableGuid. >>>=20 >>> This may have to do with Python compatibility as Xcode 11 LLDB that us= es Python 3 generally crashes more often than MacPorts LLDB 9.0. Surprising= ly structures work more or less fine. >>>=20 >>=20 >> You can tell lldb to use the older Python like this (from the Terminal.= app): >> $ defaults write com.apple.dt.lldb DefaultPythonVersion 2 >>=20 >>> 4. Ctrl+C does not produce a valid backtrace. When I break with a brea= kpoint, I see a proper stacktrace with more than one entry, with function p= rototypes and values. When I break with Ctrl+C I only see some weird backtr= ace with most of the entries missing regardless of frame position: >>>=20 >>> (lldb) bt >>> * thread #1, stop reason =3D signal SIGTRAP >>> * frame #0: 0x000000007fe4c5f3 DxeCore.dll >>>=20 >>> Probably more and all the unintuitive stuff like the lack of more func= tional TUI, but it is hard to remember all the trials. >>>=20 >>=20 >> For the macOS API clang emits frame pointers, so you can walk the stack= without symbols. You could try adding the compiler flag to emit the frame = pointers.=20 >>=20 >>=20 >>> [1] https://github.com/acidanthera/OpenCorePkg/blob/master/Debug/Scrip= ts/lldb_uefi.py >>>=20 >>=20 >> On macOS the Mach-O and dSYM have a UUID (dwarfdump -u) that is indexed= by Spotlight (mdfind "com_apple_xcode_dsym_uuids =3D=3D *") [2] >> This should be the UUID in the debug directory entry and you can use th= at to lookup the symbols like this: >>=20 >> module =3D target.AddModule (None, None, uuid) >> SBError =3D target.SetModuleLoadAddress (module, LoadAddress + TeAdjust= ) >>=20 >> Also lldb has built in help for commands, but it is kind of terse since= it is autogenerated from the C++ swig.=20 >> (lldb) script help (lldb.target.AddModule) >> Help on method AddModule in module lldb: >>=20 >> AddModule(self, *args) method of lldb.SBTarget instance >> AddModule(SBTarget self, SBModule module) -> bool >> AddModule(SBTarget self, char const * path, char const * triple, ch= ar const * uuid) -> SBModule >> AddModule(SBTarget self, char const * path, char const * triple, ch= ar const * uuid_cstr, char const * symfile) -> SBModule >> AddModule(SBTarget self, SBModuleSpec module_spec) -> SBModule >>=20 >> The minimum you need to symbolicate a frame is uuid, LoadAddress, and = PC.=20 >>=20 >> [1] http://lldb.llvm.org/use/map.html >> [2] http://lldb.llvm.org/use/symbols.html >>=20 >> Thanks, >>=20 >> Andrew Fish >>=20 >>=20 >>> Best wishes, >>> Vitaly >>>=20 >>>> 20 =D0=BC=D0=B0=D1=80=D1=82=D0=B0 2020 =D0=B3., =D0=B2 22:14, Andrew = Fish > =D0=BD=D0=B0=D0=BF=D0=B8=D1= = =81=D0=B0=D0=BB(=D0=B0): >>>>=20 >>>>=20 >>>>=20 >>>>> On Mar 20, 2020, at 8:13 AM, Vitaly Cheptsov > wrote: >>>>>=20 >>>>> Hello, >>>>>=20 >>>>> We noticed that the original bugzilla, which intended to add new LLV= M toolchain support[1], also wanted to bring ELF format support with DWARF = debugging information. For some reason this did not make its way into EDK I= I, and we are currently wondering, how can one debug binaries built with LL= VM 9.0. >>>>>=20 >>>>> For macOS and XCODE5 toolchain we use GDB scripts based on Andrei Wa= rkentin=E2=80=99s work, which allow us to integrate with QEMU and VMware[2]= . It is likely that they should work with little to no work on Linux with C= LANG38/GCC5 with GDB once again. However, CLANGPDB apparently is using PDB = debugging information, which I believe is not handled with GDB. >>>>>=20 >>>>> Could you please provide the details on the matter and let us know a= bout the recommended route? >>>>> =E2=80=94 Is dropping CLANGELF just a temporary measure and it shoul= d be resubmitted again? >>>>> =E2=80=94 Should LLDB, which seems to be aware of PDB, be used inste= ad of GDB, when building with CLANGPDB? If so, did anybody try that? >>>>>=20 >>>>=20 >>>> Vitaly, >>>>=20 >>>> I've not tried the CLANGPDB path, but if you want to connect lldb to = QEMU you need to set plugin.process.gdb-remote.target-definition-file [1] = to [2].=20 >>>>=20 >>>> [1] lldb -o "settings set plugin.process.gdb-remote.target-definitio= n-file x86_64_target_definition.py" -o "gdb-remote 9000" >>>> [2] https://github.com/llvm-mirror/lldb/blob/master/examples/python/x= 86_64_target_definition.py >>>>=20 >>>> Thanks, >>>>=20 >>>> Andrew Fish >>>>=20 >>>>> Thanks! >>>>>=20 >>>>> Best regards, >>>>> Vitaly >>>>>=20 >>>>> [1] https://bugzilla.tianocore.org/show_bug.cgi?id=3D1603 >>>>> [2] https://github.com/acidanthera/OpenCorePkg/blob/master/Debug/Scr= ipts/gdb_uefi.py >>>>>=20 >>>=20 >=20 >=20 > --Apple-Mail=_512E4AC5-7B40-438E-B895-B27522CB28B2 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8

On Mar 21, 2= 020, at 11:36 AM, Vitaly Cheptsov <cheptsov@ispras.ru> wrote:

Andrew,

Thanks once again, but unfortunately it is not that simple. Below I answered inline e= xplaining the particular issues, which mostly seem to be specific to CLANGPDB. LLVM stack emits PDB debug fil= es, and even though LLDB does support them to some level, it is unlikely th= at this will be working well enough soon. We should really stick to more or= less native debug formats, ideally those that have proper open specificati= ons, on all platforms, and for Unix that=E2=80=99s DWARF.

=

Vitaly,

= I understand and I use the Xcode clang and not the CLANGPDB, but I use lldb= a lot I was just trying to point out what works with Xcode. 


=
I am pretty sure LL= VM can be taught to emit DWARF debug information even for PE files. Perhaps= we can either make some option or provide a separate toolchain for this? A= nother way would be recovering CLANGELF as originally suggested.

=

There was a bug recently in the &n= bsp;x86_64-pc-win32-macho triple and we had to add -gdwarf to force it= emit dwarf. Not sure what that compiler flag would do to CLANGPDB but it i= s worth a try? Last flag wins for the compiler. 
=

You can teach lldb about types. Th= ere is some example code here: https://github.co= m/tianocore/edk2/blob/master/EmulatorPkg/Unix/lldbefi.py

This code works just fine with LLD= B and DWARF (e.g. XCODE5), though I have not yet completed these changes fo= r my scripts for LLDB, only for GDB. However, with CLANGPDB generated files= it is not functional. The reason for this is because LLDB is unaware of th= e underlying type, i.e. it does not know what is EFI_STATUS or UINT32. I ca= n implement pretty-printing when LLDB knows about a typedef, but it is not = possible to do this when the debug information is already gone or not parse= d:

(lldb) p Status
(unsigned l= ong long) $1 =3D 0
(lldb) p &Status
(unsign= ed long long *) $2 =3D 0x000000007fe19ad8
(lldb) p (EFI_STATU= S)Status
error: use of undeclared identifier 'EFI_STATUS'

J= ust in case I tried using exactly your code, and other stuff like source le= vel debugging works just fine and symbolication works fine, so it should be= some bug with PDB in particular.

That is s= trange as globals usually work best? The common issue I've seen is getting = the slide wrong. The EFI modules are linked at a value near zero and reloca= ted into memory, so the slide represents that adjustment. 

You can use `image dump sect= ions` and ` image dump symtab` to see lldb's view of symbols. More inf= o here [1]. 

Ye= s, this one is a bit complicated, once again due to PDB most likely. It kno= ws about global symbols, but does not list them in symtab:

(lldb) image dump symtabDumping symbol table for 91 modules.
Symtab, fil= e =3D GdbSyms/Bin/X64_CLANGPDB/GdbSyms.dll, num_symbols =3D 0
Symtab, file =3D /Users/user/Documents/UefiWorkspace/Build/OvmfX64/NOOPT_C= LANGPDB/X64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll, num_symbols = =3D 0
Symtab, file =3D /Users/user/Documents/UefiWorkspace/B= uild/OvmfX64/NOOPT_CLANGPDB/X64/MdeModulePkg/Universal/DevicePathDxe/Device= PathDxe/DEBUG/DevicePathDxe.dll, num_symbols =3D 0
=E2= = =80=A6

The slide= s are correct, but there are two nuances that collide with it.

1. There are multiple instanc= es of the globals with the same name (e.g. gBS), but for some reason LLDB a= lways tries to print the globals from the first module. This happens even w= hen I am source-level debugging, and I see a gBS symbol from another module= (e.g. DxeCore) used right at the same line. With GDB the closest symbol is= used, but with LLDB it is always coming from the first module. I tried che= cking expr help to find whether I can pass it a module explicitly, but also= failed.


Usually what happens with lldb is you get t= he global that is in scope for the current frame. 

2.  To be able to get EFI types to= locate the EFI_SYSTEM_TABLE_POINTER I add a dummy GdbSyms image, which is = not loaded to the firmware. So basically I cannot slide what is not in the = memory, and this is also my first image. I tried deleting it anyhow, but it= failed for me.


I've not used the fake image to get = things done so I can't speak to that. I have used a fake target so I could = have XIP PEIM and shadowed PEIM address available at the same time. You can= 't have a module loaded at 2 addresses at the same time in llldb. But you m= ight be able to use a fake target for your fake stuff?

Just in case:

&n= bsp;         # create a faka target to store info about= symbols
          PeiXipTarget =3D targ= et.debugger.CreateTarget (None, "i386-apple-macosx", "remote-macosx", True,= error)

        &nb= sp; # make sure the gdb-remote  connection target is the active target=
          target.debugger.SetSelectedTa= rget (target)


(lldb) image dump sections
Dumping sections for 91 modules.
Sections for '= GdbSyms/Bin/X64_CLANGPDB/GdbSyms.dll' (x86_64):
  S= ectID     Type           =   Load Address             &nb= sp;               Perm File Off.&nb= sp; File Size  Flags      Section Name  ---------- ---------------- ----------------------= -----------------  ---- ---------- ---------- ---------- --------= --------------------
  0xffffffffffffffff container=         [0x0000000000000000-0x0000000000006ec0)* -= --  0x00000000 0x00000000 0x00000000 GdbSyms.dll.
&= nbsp; 0x00000001 code            &n= bsp;[0x0000000000000220-0x0000000000005bd6)* ---  0x00000220 0x00= 0059c0 0x60000020 GdbSyms.dll...text
  0x00000002 d= ata             [0x0000000000005be0= -0x0000000000006d79)* ---  0x00005be0 0x000011a0 0x40000040 GdbSy= ms.dll...rdata
  0x00000003 data    =         [0x0000000000006d80-0x0000000000006e30)* = ---  0x00006d80 0x00000060 0xc0000040 GdbSyms.dll...data
  0x00000004 regular         &nbs= p;[0x0000000000006e40-0x0000000000006ea4)* ---  0x00006de0 0x0000= 0080 0x42000040 GdbSyms.dll...reloc
Sections for '/Users/user= /Documents/UefiWorkspace/Build/OvmfX64/NOOPT_CLANGPDB/X64/MdeModulePkg/Core= /Dxe/DxeMain/DEBUG/DxeCore.dll' (x86_64):
  SectID&= nbsp;    Type            =  Load Address               &n= bsp;             Perm File Off. &nb= sp;File Size  Flags      Section Name
  ---------- ---------------- ----------------------------= -----------  ---- ---------- ---------- ---------- --------------= --------------
  0xffffffffffffffff container =       [0x0000000000000000-0x00000000000523a0)* ---&nbs= p; 0x00000000 0x00000000 0x00000000 DxeCore.dll.
 &= nbsp;0x00000001 code             [0= x000000007fe1b220-0x000000007fe61e34)  ---  0x00000220 = 0x00046c20 0x60000020 DxeCore.dll...text
  0x000000= 02 data             [0x000000007fe6= 1e40-0x000000007fe68065)  ---  0x00046e40 0x00006240 0x= 40000040 DxeCore.dll...rdata
  0x00000003 data = ;            [0x000000007fe68080-0x00000= 0007fe6d160)  ---  0x0004d080 0x000018a0 0xc0000040 Dxe= Core.dll...data
  0x00000004 regular    &= nbsp;     [0x000000007fe6d160-0x000000007fe6d398)  = ;---  0x0004e920 0x00000240 0x42000040 DxeCore.dll...reloc
Sections for '/Users/user/Documents/UefiWorkspace/Build/OvmfX64/NOO= PT_CLANGPDB/X64/MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe/DEBUG/De= vicePathDxe.dll' (x86_64):
  SectID   &nb= sp; Type             Load Addr= ess                   &nb= sp;         Perm File Off.  File Size&nb= sp; Flags      Section Name
 &n= bsp;---------- ---------------- ---------------------------------------&nbs= p; ---- ---------- ---------- ---------- ----------------------------<= br class=3D"">  0xffffffffffffffff container      =   [0x0000000000000000-0x0000000000014420)* ---  0x00000= 000 0x00000000 0x00000000 DevicePathDxe.dll.
  0x00= 000001 code             [0x00000000= 7f986220-0x000000007f996cc6)  ---  0x00000220 0x00010ac= 0 0x60000020 DevicePathDxe.dll...text
  0x00000002 = data             [0x000000007f996ce= 0-0x000000007f999b04)  ---  0x00010ce0 0x00002e40 0x400= 00040 DevicePathDxe.dll...rdata
  0x00000003 data&n= bsp;            [0x000000007f999b20-0x00= 0000007f99a1a2)  ---  0x00013b20 0x00000660 0xc0000040 = DevicePathDxe.dll...data
  0x00000004 regular =         [0x000000007f99a1c0-0x000000007f99a404)&n= bsp; ---  0x00014180 0x00000260 0x42000040 DevicePathDxe.dll= = =E2=80=A6reloc
=E2=80=A6

So, all in all, unique global variables work, but th= ere is no way to access duplicating variables. They either resolve to GdbSy= ms or just cause a crash:

(lldb) p mDebugInfoTableHeader
(EFI_DEBUG_IMAGE= _INFO_TABLE_HEADER) $0 =3D {
  UpdateStatus =3D 2  TableSize =3D 92
  EfiDebu= gImageInfoTable =3D 0x000000007f814018
}
(lldb)=  p gBS
error: Couldn't materialize: couldn't get the val= ue of variable ::gBS: read memory from 0x6df8 failed
error: e= rrored out in DoExecute, couldn't PrepareToExecuteJITExpression
(lldb) p gEfiGlobalVariableGuid
0  libLLVM.= dylib            0x000000010e52ee68 llvm= ::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1 &n= bsp;libLLVM.dylib            0x000000010= e52f262 SignalHandler(int) + 188
2  libsystem_platf= orm.dylib 0x00007fff6ca5642d _sigtramp + 29
...


<= /div>
If you want to inspect globals I think this logic works to get yo= u data, you would need to print it out etc. 

=
SBValueList =3D lldb.target.FindGlobalVariables ("gST", 1024)
for SBValue in SBValueList:
Module =3D SBValue.GetAddress().GetM= odule() 
        ModuleStr =3D SBValue.G= etAddress().GetModule().GetFileSpec().GetFilename()
&n= bsp;       Start =3D int (SBValue.GetLocation(), 0)
        End =3D Start + SBValue.GetByteSiz= e() - 1
        = SBDeclaration =3D SBValue.GetDeclaration()
        Column =3D SBDeclaration.GetColumn()

I wrote a command in the early days to dump out all = the instances of a global. 

=
You can also try (lldb) image lookup -Av --name gST
You can tell lldb to use the older Python like thi= s (from the Terminal.app):
$ defaults write com.a= pple.dt.lldb DefaultPythonVersion 2

=
Thanks, that helped quite a bit, but for some reason Xcode = version still crashes more for me. I attached a couple of stack traces if y= ou feel like having a look, but once again it seems that it is all about th= e PDB plugin.

For the macOS API clang e= mits frame pointers, so you can walk the stack without symbols. You could t= ry adding the compiler flag to emit the frame pointers. 


This is easy enough to c= heck as %rpb is the frame pointer so it will get saved/restored on function= entry/exit. 

I am pretty sure stack frames are not disabled with UEFI, as = sometimes backtracing works just fine. To me it looks like debug informatio= n parsing randomly breaks in LLDB, and once it happens it forgets about oth= er images:

(lldb)=  b CoreLocateHandleBuffer
Breakpoint 2: where =3D DxeCor= e.dll`CoreLocateHandleBuffer + 31 at Locate.c:649, address =3D 0x000000007f= e36e4f
(lldb) c
Process 1 resuming
Process 1 stopped
* thread #1, stop reason =3D br= eakpoint 2.1
    frame #0: 0x000000007fe3= 6e4f DxeCore.dll`CoreLocateHandleBuffer(SearchType=3DByProtocol, Proto= col=3D0x000000007f978160, SearchKey=3D0x0000000000000000, NumberHandles=3D0= x000000007fe19fd8, Buffer=3D0x000000007fe19fc0) at Locate.c:649   646    EFI_STATUS       = ;   Status;
   647    UINTN &n= bsp;             BufferSize;
   648 
-> 649    if (NumberHandles = =3D=3D NULL) {
   650      return = EFI_INVALID_PARAMETER;
   651    }
   652 
(lldb) bt
* thread #= 1, stop reason =3D breakpoint 2.1
  * frame #0= : 0x000000007fe36e4f DxeCore.dll`CoreLocateHandleBuffer(SearchTyp= e=3DByProtocol, Protocol=3D0x000000007f978160, SearchKey=3D0x00000000000000= 00, NumberHandles=3D0x000000007fe19fd8, Buffer=3D0x000000007fe19fc0) a= t Locate.c:649
    frame #1: 0x00000= 0007fe36816 DxeCore.dll`CoreLocateDevicePath(Protocol=3D0x000000007f97= 8160, DevicePath=3D0x000000007fe1a060, Device=3D0x000000007fe1a068) at = ;Locate.c:466
    frame #2: 0x000000007f9= 7479a SecurityStubDxe.dll

=E2=80=94=E2=80=94=E2=80=94

(lldb) b CopyMem
Breakpoint 3: 70 locations.(lldb) c
Process 1 resuming
Pr= ocess 1 stopped
* thread #1, stop reason =3D breakpoint = 2.53 3.53
    frame #0: 0x000000007e5c13b= 3 MnpDxe.dll`CopyMem(DestinationBuffer=3D0x000000007fe19b50, SourceBuf= fer=3D0x000000007e2aa470, Length=3D656) at CopyMemWrapper.c:47
   44     IN UINTN      &nb= sp;Length
   45     )
&nbs= p;  46   {
-> 47     if (Length =3D= =3D 0) {
   48       return&n= bsp;DestinationBuffer;
   49     }
   50     ASSERT ((Length - 1) <= =3D (MAX_ADDRESS - (UINTN)DestinationBuffer));
(lldb) b= t
* thread #1, stop reason =3D breakpoint 2.53 3.53
  * frame #0: 0x000000007e5c13b3 MnpDxe.dll`C= opyMem(DestinationBuffer=3D0x000000007fe19b50, SourceBuffer=3D0x000000007e2= aa470, Length=3D656) at CopyMemWrapper.c:47
(lldb) = finish
error: Could not create return address breakpoint.
(lldb) n
Process 1 stopped
* th= read #1, stop reason =3D step over
    fr= ame #0: 0x000000007e5c13ce MnpDxe.dll`CopyMem(DestinationBuffer= =3D0x000000007fe19b50, SourceBuffer=3D0x000000007e2aa470, Length=3D656) at=  CopyMemWrapper.c:50
   47     if&n= bsp;(Length =3D=3D 0) {
   48      =  return DestinationBuffer;
   49 &nb= sp;  = ; }
-> 50     ASSERT ((Length - 1) &l= t;=3D (MAX_ADDRESS - (UINTN)DestinationBuffer));
   = ;51   =   ASSERT ((Length - 1) <=3D (MAX_ADDRESS - (UINTN)= SourceBuffer));
   52  
  &nbs= p;53  =   if (DestinationBuffer =3D=3D SourceBuffer) {
(lldb)  
...
Process 1 stopp= ed
* thread #1, stop reason =3D step over
=     frame #0: 0x000000007e5c14b4 MnpDxe.dll`CopyMe= m(DestinationBuffer=3D0x000000007fe19b50, SourceBuffer=3D0x000000007e2aa470= , Length=3D656) at CopyMemWrapper.c:57
   54&n= bsp;      return DestinationBuffer;
  &n= bsp;55     56     return=  InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);
-> 57   }
(lldb)  
Process= 1 stopped
* thread #1, stop reason =3D step over
    frame #0: 0x000000007e5c726e MnpDxe.dl= l
->  0x7e5c726e: mov    rax, qwo= rd ptr [rsp + 0x60]
    0x7e5c7273: cmp  =   byte ptr [rax + 0x68], 0x0
    0x7= e5c7277: jne    0x7e5c7291
    = 0x7e5c727d: movabs rax, -0x7fffffffffffffed
(lldb) bt* thread #1, stop reason =3D step over
  * frame #0: 0x000000007e5c726e MnpDxe.dll&= nbsp;

=E2= =80=94=E2=80=94=E2=80=94

(lldb) c
Process 1 resuming
Proce= ss 1 stopped
* thread #1, stop reason =3D signal SIGINT<= br class=3D"">    frame #0: 0x000000007fe4d72e Dxe= Core.dll
->  0x7fe4d72e: cmp    a= l, 0x0
    0x7fe4d730: je    &n= bsp;0x7fe4d765
    0x7fe4d736: mov   = ; rcx, qword ptr [rsp + 0x20]
    0x7fe4d= 73b: call   0x7fe4c4b0
(lldb) bt
* thread #1, stop reason =3D signal SIGINT
 =  * frame #0: 0x000000007fe4d72e DxeCore.dll

On macOS the Mach-O and dSYM have a UUID (dwarfdump = -u) that is indexed by Spotlight (mdfind "com_apple_xcode_dsym_uuids =3D=3D= *") [2]
This should be the UUID in the debug director= y entry and you can use that to lookup the symbols like this:

module =3D target.AddModule (N= one, None, uuid)
SBError =3D target.SetModuleLoadAddre= ss (module, LoadAddress + TeAdjust)

Also lldb has built in help for commands, but it is kind= of terse since it is autogenerated from the C++ swig. 
(lldb) script help (lldb.target.AddModule)
Help on method AddModule in module lldb:

AddModule(s= elf, *args) method of lldb.SBTarget instance
    AddModule(SBTarget self, SBModule modu= le) -> bool
  =   AddModule(SBTarget self, char const * path, char const * triple, cha= r const * uuid) -> SBModule
    AddModule(SBTarget self, char const * path, char con= st * triple, char const * uuid_cstr, char const * symfile) -> SBModule
    AddModule= (SBTarget self, SBModuleSpec module_spec) -> SBModule

The minimum  you ne= ed to symbolicate a frame is uuid, LoadAddress, and PC. 
<= /div>


Thanks for the links ag= ain. Yes, I am using some of these, and in fact for GDB that=E2=80=99s pret= ty much what I did when I worked with XCODE5. It is very likely that when I= get to complete LLDB support for XCODE5 it will work quite fine too. But I= am already happy with XCODE5 here, and making it even better will only hel= p myself, but not other people with e.g. Linux or people that want me to us= e the same compiler with them.


Thanks for looking ou= t for others. 

Thanks,
<= br class=3D"">
Andrew Fish

Best regards,
Vitaly


<= /div>
2= 1 =D0=BC=D0=B0=D1=80=D1=82=D0=B0 2020 =D0=B3., =D0=B2 20:13, Andrew Fish &l= t;afish@apple.com> =D0= = =BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB(=D0=B0):



<= div class=3D"">On Mar 21, 2020, at 3:28 AM, Vitaly Cheptsov <cheptsov@ispras.ru> wrote:
Hello,

Andrey, thanks for the hint, it was very hel= pful. I rewrote the GDB scripts to work with LLDB[1] and was able to debug = OVMF built with CLANGPDB. While it is still quite dirty, at the very least = it works.

Unfortunately the experience was c= lose to terrible. I may certainly do something wrong, but it is clear that = PDB and LLDB do not support each other well enough. After spending several = hours on playing with the tools my conclusion is that LLDB is simply not su= ited for UEFI PDB debugging, and we really want DWARF  as there is no = other opensource debugger that supports PDB on macOS and Linux

In case somebody knows workarounds here are the issues = I faced:

=
1. All integer alias typedefs are d= iscarded in favour of underlying types. This way EFI_STATUS and EFI_TPL bec= ome unsigned long long, CHAR8 becomes char, and CHAR16 becomes unsigned sho= rt. It does not look like LLDB has the original types anywhere at all, and = it also does not have them registered.

 = ;   frame #0: 0x000000007fe242aa DxeCore.dll`CoreAlloca= tePoolPagesI(PoolType=3DEfiBootServicesData, NoPages=3D1, Granularity=3D409= 6, NeedGuard=3D'\0') at Pool.c:322
   319 = ;   =   return NULL;
   320    }
   321 
-> 322    Buffer =3D CoreA= llocatePoolPages (PoolType, NoPages, Granularity, NeedGuard);
   323    CoreReleaseMemoryLock ();
  &= nbsp;324  <= /span>
   325    if (Buffer !=3D NULL) {=
(lldb) p Status
(unsigned long long) $3 = =3D 0

Structures work more or less fine, but for simpler types l= ike strings we are out of even potential pretty-printing.

=

Vitaly,

You can te= ach lldb about types. There is some example code here: https://github.com/tianocore/edk2/blob/master/EmulatorPkg/Unix/lldbe= fi.py

2. Glo= bal variables are not accessible. I am not sure what happens, but they eith= er seem to not relocate or conflict with the other names:

(lldb) p gST
error: Couldn't materia= lize: couldn't get the value of variable ::gST: read memory from 0x6e18 fai= led
error: errored out in DoExecute, couldn't PrepareToExecut= eJITExpression
(lldb) p &gST
error: Co= uldn't materialize: couldn't get the value of variable ::gST: read memory f= rom 0x6e18 failed
error: errored out in DoExecute, couldn't P= repareToExecuteJITExpression
<= br class=3D"">

That is st= range as globals usually work best? The common issue I've seen is getting t= he slide wrong. The EFI modules are linked at a value near zero and relocat= ed into memory, so the slide represents that adjustment. 

You can use `image dump sections` and ` image dump= symtab` to see lldb's view of symbols. More info here [1]. 

3. Quite a number of cras= hes.

In most cases autocompletion by tab pre= ss causes a crash. E.g.

b I<TAB>
=

So will do printing of a GUID, e.g. p gEfiGlobalVar= iableGuid.

This may have to do with Python compatibility as Xcode 11 = LLDB that uses Python 3 generally crashes more often than MacPorts LLDB 9.0= . Surprisingly structures work more or less fine.


You can tell lldb to use the older Python like this (fr= om the Terminal.app):
$ d= efaults write com.apple.dt.lldb DefaultPythonVersion 2

<= div class=3D"" 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-stro= ke-width: 0px; text-decoration: none;">4. Ctrl+C does not produce a valid backtrac= e. When I break with a breakpoint, I see a proper stacktrace with more than= one entry, with function prototypes and values. When I break with Ctrl+C I= only see some weird backtrace with most of the entries missing regardless = of frame position:

(lldb) bt
* thread #1, stop re= ason =3D signal SIGTRAP
  * frame #0: 0x0= 00000007fe4c5f3 DxeCore.dll

Probably more and all the unintuitive stuff like the lack of more= functional TUI, but it is hard to remember all the trials.


For the macOS API clang emits frame pointers= , so you can walk the stack without symbols. You could try adding the compi= ler flag to emit the frame pointers. 

<= br class=3D"">

=
On macOS the Mach-O and dSYM = have a UUID (dwarfdump -u) that is indexed by Spotlight (mdfind "com_apple_= xcode_dsym_uuids =3D=3D *") [2]

module =3D= target.AddModule (None, None, uuid)
SBError =3D target.SetModuleLoadAddress (module, LoadAddress + TeAdj= ust)

Also lldb has built in help for command= s, but it is kind of terse since it is autogenerated from the C++ swig.&nbs= p;
(lldb) script help (lldb.target.AddModule)
=
Help on method AddModule in module= lldb:

= Add= Module(self, *args) method of lldb.SBTarget instance
    AddModule(SBTarget self, SBMo= dule module) -> bool
    AddModule(SBTarget self, char const * pa= th, char const * triple, char const * uuid_cstr, char const * symfile) ->= ; SBModule
  &nbs= p; AddModule(SBTarget self, SBModuleSpec module_spec) -> SBModule=

The minimum &= nbsp;you need to symbolicate a frame is uuid, LoadAddress, and PC. 
Best wishes,
Vitaly

20 =D0=BC=D0=B0=D1=80=D1=82=D0=B0 2020 =D0=B3., =D0= =B2 22:14, Andrew Fish <a= fish@apple.com> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB(=D0=B0):<= /div>


On Mar 20, 2020, at 8:13 AM, Vitaly= Cheptsov <cheptsov@isp= ras.ru> wrote:

Hello,

We noticed that the original bugzilla, which intende= d to add new LLVM toolchain support[1], also wanted to bring ELF format sup= port with DWARF debugging information. For some reason this did not make its way into EDK I= I, and we are currently wondering, how can one debug binaries built with LL= VM 9.0.

For macOS and XCODE5 toolchain we use= GDB scripts based on Andrei Warkentin=E2=80= =99s work, which allow us to integrate with QEMU and VMware[2]. It is like= ly that they should work with little to no work on Linux with CLANG38/GCC5 = with GDB once again. However, CLANGPDB apparently is using PDB debugging in= formation, which I believe is not handled with GDB.

Could you please provide the de= tails on the matter and let us know about the recommended route?
=E2=80=94 Is dropping CLANGELF just a temporary measure and it s= hould be resubmitted again?
=E2=80=94 Should LLDB, which seems to be = aware of PDB, be used instead of GDB, when building with CLANGPDB? If so, d= id anybody try that?


Vitaly,

I've= not tried the CLANGPDB path, but if you want to connect lldb to QEMU you n= eed to set  plugin.process.gdb-remote.target-definition-file [1] to [2= ]. 

=
[1]  lldb -o "settings se= t plugin.process.gdb-remote.target-definition-file x86_64_target_definition= .py" -o "gdb-remote 9000"



<crashes.tx= t>
--Apple-Mail=_512E4AC5-7B40-438E-B895-B27522CB28B2--