-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document how to debug an application built with uefi-rs #289
Comments
I found this article, but their approach doesn't seem to work. It finds the base address and address of each section, but still doesn't provide any symbols to gdb. Then I found a |
Previous versions of IIRC, the spec requires that UEFI apps tick a few boxes, e.g. the subsystem type, but it also states that they ought to be stripped, hence this behavior. |
The executable should be stripped, but applications built in C with EDK2 in With that in mind, it sounds like this might be worth filing a bug for the |
I'm in the process of bisecting compiler versions to determine where the old behavior of having symbol tables was lost. |
The last build that provides symbol tables is I'll try to do some digging as to why that happens, but I don't know the first thing about rustc or cargo code so I don't expect to find the solution TBH. MethodologyI took
For building,
|
Bisecting leads to rust-lang/rust#78959, which is also linked to by rust-lang/rust#87157 where the author of the blog post above reports the same issue. The solution seems to be to do |
Can confirm the above solution works, with the additional step of removing "is-builtin" from the target file. I'll dive into debugging something in QEMU tonight, but this looks like it solves the issue completely as gdb can see all symbols and map them back to the source files. |
I'm not seeing quite the same thing as you with the builtin x86_64-unknown-uefi target. I do get what seems to be a valid pdb file generated under the So if I'm understanding correctly, rustc used to include DWARF-style debug sections in the executable, and now it outputs a pdb. Which does seem like reasonable behavior. lldb seems like it supports loading pdb files (either with a Windows-specific loader, or the "native pdb" plugin on other platforms), but in testing on Linux I haven't had any luck getting it to successfully load symbols. |
Yeah, that's the same issue that I was having with the pdb files. I tested on both linux and windows(mingw) and was unable to correctly load any symbols. I'll give MSVC a try. With @no92's solution, gdb and lldb in linux are able to recognize the symbols enough to say they have successfully set a breakpoint, but they won't actually break with EDIT: Tried to fixup the addresses using the above article, but it segfaulted while running on my machine. |
@nicholasbishop wrote:
I had checked it with some pdb tool I frankly can't remember right now, and I didn't find anything resembling symbols. It was, however, a valid pdb file. As it was some random tool pulled from GitHub, it could just be wrong and the Rust crate right. Oops. @timrobertsdev wrote:
As EFI apps are relocatable, the base address changes. This could be read out via the LoadedImage Protocol, but transferring that info from the remote to the debugger host would have to take place somehow. Alternatively, the instructions in the article work for me, I'm not sure why it's segfaulting for you. I use the python script via a |
@no92 Nevermind, I got it working. The mistake I was making was attempting to run the |
I believe I've taken all the steps mentioned above yet the problem persists -- GDB is not able to recognize any symbols (which I doubt exist). I might've missed something. Any help would be much appreciated. What I did:
|
While I haven't used this in a while, rolling back to an old nightly version should not be necessary. Using the script provided in the blog post linked above is necessary IIRC. |
Unfortunately, it still doesn't work for me. We're talking about |
I have successfully solved the problem by adding the following build (under the [build] section) flag in .cargo/config:
Thanks to the following video: This might be trivial to some however I wasn't aware of this link argument in the first place. |
How did you get it working with gdb? I can't seem to figure it out |
This enables for example |
I've been digging around this issue recently, here's what I've discovered so far. I've been trying to use LLDB, since it is the only debugger which can read PDB files (in theory) and connect to QEMU using GDB's remote debug protocol. I've tried to follow along with the instructions from this article on the osdev.org wiki. I've modified the {
let loaded_image = st.boot_services()
.open_protocol_exclusive::<LoadedImage>(image)
.expect("Failed to open LoadedImage protocol");
println!("Image base: {:#X}", loaded_image.info().0 as usize);
}
let wait = true;
while wait { } When running the app with Now, I ran the following commands in LLDB, from the
At this point, everything should be set up for debugging. Unfortunately, LLDB just crashes:
I'm guessing it tries to parse the PDB file and the current stack frame, but it triggers some bug somewhere. I haven't submitted a bug report to LLDB yet, I'm going to play around with this setup for a bit longer. |
@GabrielMajeri I managed to replicate your process in VSCode and LLDB shell as well |
The pdb files not being copied is a cargo bug: rust-lang/cargo#5179 did not include -uefi as a target to copy pdbs for. I don't feel like filing an actual bug right now; I'm presently testing just patching it and I may file a PR later. |
EFI also uses the PE format with .pdb files, and rustc generates them, but Cargo does not copy them out of target/*/deps. This is an oversight, so this PR fixes it. Related: rust-osdev/uefi-rs#289 Related: rust-lang#5179
@GabrielMajeri This may be because the virtual address of .text in your image is not 0. You can check the virtual addresses of all sections by using
Then |
After a week of struggle, I finally realized that using LLDB to debug UEFI applications is far from mature. And I still cannot let the rustc and lld to output dwarf debug symbols. The line below seems to have no effect on me.
|
The following addition in [target.x86_64-unknown-uefi]
rustflags = ["-C", "link-args=/debug:dwarf"] The only solution seems to be the following as mention earlier. Hopefully it will help someone in the future.
I also needed the following additions to my [unstable]
build-std = ["core", "compiler_builtins", "alloc"]
build-std-features = ["compiler-builtins-mem"] With that the target (x86_64-unknown-uefi-debug.json) can then be built with nightly cargo +nightly build --target x86_64-unknown-uefi-debug.json The resulting .efi file will then have debug info which will work with gdb
|
Splitting this out from #285:
@timrobertsdev wrote:
I don't know the answer to this, but it would be nice to have a straightforward way to debug an application built with uefi-rs running under qemu. I'm not sure if there is something that currently works and it just needs some documentation, or if there's work needed in the toolchain.
The text was updated successfully, but these errors were encountered: