QEMU: Make PDB path/name deterministic#58
Conversation
Explicitly specifying the PDB name via `PDBALTPATH` improves debugger usability
for several reasons:
1. Cargo copies the final `.efi` and its `.pdb` to
`target\<target-triple>\[debug|release]` as `qemu_sbsa_dxe_core.efi`(no hash
appended.
2. Full paths embedded in the PDB generated on WSL make it harder for the
debugger to map the `.efi` to the `.pdb` on Windows.
3. Without this PR, the PDB file name is non-deterministic (it includes a hash),
even though it contains the full path, making debugging/scripting tedious.
4. As long as the `.efi` and `.pdb` files are in the same directory, WinDbg can
easily pick up the PDB file without any manual fixes.
5. Even if they are not in the same directory, `.sympath+` can be used to point
WinDbg to the directory containing the pdb files.
Since WinDbg checks the current directory for the PDB by default, based on the
path embedded in the .efi, providing just the file name (not the full path) for
PDBALTPATH allows the debugger to locate it easily without requiring any file
renames.
```
Option 1: Without the PDBALTPATH option
Debug Directories(1)
Type Size Address Pointer
cv 3f 1b1074 1afa74 Format: RSDS, guid, 1, qemu_sbsa_dxe_core-b3e9a890bb6be3ce.pdb
Option 2: -C link-arg=/PDBALTPATH:%_PDB% # This is the default behaviour by rustc.
Debug Directories(1)
Type Size Address Pointer
cv 3f 1b1074 1afa74 Format: RSDS, guid, 1, qemu_sbsa_dxe_core-f3080c9eaed3fe01.pdb
Option 3: -C link-arg=/PDBALTPATH: # only useful on Windows, that too, only if the path exists(not useful for remote/offline debugging)
Debug Directories(1)
Type Size Address Pointer
cv 83 1b1074 1afa74 Format: RSDS, guid, 1, E:\repos\patina-dxe-core-qemu\target\aarch64-unknown-uefi\debug\deps\qemu_sbsa_dxe_core-765fdbf691f03726.pdb
Option 4: -C link-arg=/PDBALTPATH:qemu_sbsa_dxe_core.pdb
Debug Directories(1)
Type Size Address Pointer
cv 2e 1b1074 1afa74 Format: RSDS, guid, 1, qemu_sbsa_dxe_core.pdb
```
Signed-off-by: Vineel Kovvuri[MSFT] <vineelko@microsoft.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
I like getting rid of the hash, but I also think the full path is nice for automatic symbol resolution. Today the problem is that the pdbaltpath doesn’t have the right value, so you have to manually add a symbol path in the debugger.
My preference would be: use the full path and don’t create the binary/pdb with a hash in the name.
The full path allows for automatic symbol resolution, but it doesn’t prevent manual symbol inclusion either, e.g. the case where you built in WSL and then copy the pdb to Windows (or point directly into WSL which sometimes works).
I’m not following how WinDbg is automatically picking up the pdb in the scenario you are describing, you are saying WinDbg knows the path to the efi binary from somewhere and so searches that directory? If so, that works, too, I just want automatic symbol resolution, don’t care the path.
|
Given that this is only affecting the QEMU DXE Core build, I'm also primarily interested in automatic symbol resolution since this will commonly be built and run on the same system as QEMU and the source debugger. However, I think somewhere in our platform integration docs, the tradeoffs should be called out for different approaches and they could be used with the Patina debugger. In particular, it's common on real platforms to debug a build from a CI agent or another host system so the symbols need to be mapped. If that's not already documented somewhere walking through that kind of scenario would probably be helpful for others. |
|
I agree that option 3 is preferable uniquely to QEMU, but most platforms would likely want to use option 4. That said, symbol paths are persistent (usually) so it shouldn't be that inconvenient for folks to add their path. |
|
We all want the hash to get removed! But removing the hash is not a trivial option, atleast in terms of logistics, as this requires a change similar to the following for UEFI targets in the Cargo repository(we can definitely pursue that): rust-lang/cargo#7358 Putting that aside, I assume by “automatic symbol resolution” you mean that whenever you launch the .efi file in WinDbg it will automatically load the PDB, right? In fact, that is exactly what this PR is striving for. Not sure if I made it clear: the symbols get automatically resolved by WinDbg because the .pdb is sitting next to the .efi. The reason you have to manually add the symbol path today is because you are launching the .efi from the debug or release directory, which happens to contain a “-hash.pdb” embedded in it, and the .pdb sitting next to that .efi does not have the “-hash”, so WinDbg thinks it is not a match(default search behavior fails). Upon giving the path to directory containing the pdb(with the hash in the filename) it is able to locate the .pdb. This is the exact manual step I want to get rid off (and also to benefit other offline/remote scenarios). Having a full path(even without the hash) to the PDB is not desirable because it only makes the debugger happy in the one case where the path to the PDB actually exists on the filesystem. In all other cases you still need to manually teach the debugger which path to use. On top of that, if the file names don't match (because of the hash) then we need to either rename the PDB sitting next to the binary to include the hash or point to the directory containing the PDB with the hash in its filename. By not embedding the path and embedding only the file name, we solve two problems:
This is what Windows binaries also do: Lastly, this does not break any existing automatic symbol resolution workflows, even on QEMU. I have tested it. |
|
Had an offline chat with Oliver. Live Debugging Scenario: Offline Binary Inspection Scenario: Anyways, it seems there’s no perfect common ground without compromising one of our experiences. That said, I’d like to point out that by relying on full pdb path, we’re deviating from the typical workflow used when debugging physical platforms, or Windows in general, where the first step after connecting to the target is usually to run How about adding the QEMU build path to
|
This applies to physical platforms, too. If you run WinDbg from the machine you built the code for, the full path will also resolve. Nothing is QEMU specific here, except for this repo :) |
|
Yaa my bad, agreed it applies to physical platforms build from the same host. But |
I'm okay if we lose automatic symbol resolution. It's not a major pain to do the .sympath+. My main point is that consumers of Patina have liked automatic symbol resolution and we attempt to have this repo be a good representation of what platforms should do/would like to do. I think your current use case is pretty niche. Outside of the stacktrace debugging I'm assuming you are doing, I don't think that case would occur very often. So I'm more weighing is it worth losing the automatic symbol resolution for a small use case (which don't get me wrong, I believe is annoying :). I'm not overly concerned. I prefer automatic symbol resolution because it has made it easier for consumers of the debugger to pick up and go quickly without extra steps. But it's only one extra step. |
|
I'm find to take this either way. I do think we should document this in patina to allow platforms to make their own choices. |
|
I'm going to go ahead and approve because I think the conversation has reached an end. I also don't think .sympath+ is a big obstacle for someone already committed to debugging in WinDbg. In the documentation for platforms, a concise summary of tradoffs would be nice. |
|
Thanks folks, The platform docs already talks about |

Description
Explicitly specifying the PDB name via
PDBALTPATHimproves debugger usability for several reasons:.efiand its.pdbtotarget\<target-triple>\[debug|release]asqemu_sbsa_dxe_core.efi(no hash appended..efito the.pdbon Windows..efiand.pdbfiles are in the same directory, WinDbg can easily pick up the PDB file without any manual fixes..sympath+can be used to point WinDbg to the directory containing the pdb files.Since WinDbg checks the current directory for the PDB by default, based on the path embedded in the .efi, providing just the file name (not the full path) for PDBALTPATH allows the debugger to locate it easily without requiring any file renames.
Fixes #445
How This Was Tested
Validated on QEMU
Integration Instructions
Other platform specific rust dxe binaries need to incorporate a similar change to achieve a better debugging experience!