-
Notifications
You must be signed in to change notification settings - Fork 13.3k
macos: unable to get debug information from dylib dependencies #83730
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
Comments
Aha I see what's happening here. Instrumenting this function it looks like it's attemping to load a file named This temporary file is created here in the compiler and while most of the time we skip that we don't skip it if the crate is a dylib. I forget the exact reason we generate a new rlib if there's a dylib input... In any case that's the reason debuginfo doesn't work, it's because the file with the debuginfo was deleted (it was a temporary file). The fix here would probably look like one of:
After writing this I'm also now recalling that the reason for this is we call |
A related question, I can't seem to get lldb to find symbols in any rlib dependencies. Is split-debuginfo intended to work for that? Example: build cargo and set a breakpoint for
|
That sounds like a bug in something, although I have no idea what. The issue seems likely unrelated to this though? Do you know if the Also, I was struck with inspiration about this last night. The only reason we create temporary rlibs is to remove bytecode and metadata but bytecode now lives in adjacent sections in object files and we could presumably do the same thing with an empty object file for metadata as well. By ensuring that everything in an archive is an object file we can guarantee that raw rlibs can always be passed to the linker, even with Once we change the format of metadata in archives (to be a section of an empty object instead of just a raw binary file) then I think we have no need to create temporary rlibs and we can pass the rlibs as-is to the linker (basically delete all that copying-around code in the compiler related to linking) |
I believe backtrace is able to find the frames. It is able to print things like this:
In general I've noticed that lldb is having trouble with any rlib dependency (even with "packed"). I tried older versions of rust and it seems to have a lot of trouble dealing with them. Even if lldb can find the symbols, it can't find the source files, which is surprising because the absolute paths are clearly in the DWARF file. It is pretty rare that I use a debugger, so I'm not familiar with what has and has not been working in the past. It would be nice if it were a little more reliable. Anyways, whatever you said sounds good even if I don't fully understand it. |
…gisa rustc: Store metadata-in-rlibs in object files This commit updates how rustc compiler metadata is stored in rlibs. Previously metadata was stored as a raw file that has the same format as `--emit metadata`. After this commit, however, the metadata is encoded into a small object file which has one section which is the contents of the metadata. The motivation for this commit is to fix a common case where rust-lang#83730 arises. The problem is that when rustc crates a `dylib` crate type it needs to include entire rlib files into the dylib, so it passes `--whole-archive` (or the equivalent) to the linker. The problem with this, though, is that the linker will attempt to read all files in the archive. If the metadata file were left as-is (today) then the linker would generate an error saying it can't read the file. The previous solution was to alter the rlib just before linking, creating a new archive in a temporary directory which has the metadata file removed. This problem from before this commit is now removed if the metadata file is stored in an object file that the linker can read. The only caveat we have to take care of is to ensure that the linker never actually includes the contents of the object file into the final output. We apply similar tricks as the `.llvmbc` bytecode sections to do this. This involved changing the metadata loading code a bit, namely updating some of the LLVM C APIs used to use non-deprecated ones and fiddling with the lifetimes a bit to get everything to work out. Otherwise though this isn't intended to be a functional change really, only that metadata is stored differently in archives now. This should end up fixing rust-lang#83730 because by default dylibs will no longer have their rlib dependencies "altered" meaning that split-debuginfo will continue to have valid paths pointing at the original rlibs. (note that we still "alter" rlibs if LTO is enabled to remove Rust object files and we also "alter" for the #[link(cfg)] feature, but that's rarely used). Closes rust-lang#83730
On macOS, the debug information for the dependencies of a dylib do not seem to be working with split-debuginfo=unpacked.
One way to demonstrate this is building rustc itself with debug enabled, and split-debuginfo as unpacked (the default). Backtraces are unable to find the source file information for anything past
rustc_query_system
. lldb is also unable to find any debug information (it can't even find the symbols).Example of what the backtrace looks like:
Backtrace
From what I can tell, the debug information for everything directly in
rustc_driver
can be found, but anything from a dependency cannot. Note that generic functions are part ofrustc_driver
, so that is why things likerustc_middle
functions appear in the backtrace above.Minimal example
I created a simple demo project at https://github.com/ehuss/macos-dylib-debug.
This has an executable
foo
depends on dylibdriver
which depends onsomedep
.If you build on macOS with the latest nightly (2021-03-31) which has split-debuginfo enabled by default, and run with
RUST_BACKTRACE=1
, you can see that the information is missing from the dependency:If you disable split-debuginfo (
CARGO_PROFILE_DEV_SPLIT_DEBUGINFO=packed
), then it gets the full information:Similarly, trying to debug with lldb is unable to see anything in
somedep
. Running lldb with a dylib is a little tricky due to system integrity protection, it is something like this:DYLD_FALLBACK_LIBRARY_PATH=$(rustc --print=sysroot)/lib/rustlib/x86_64-apple-darwin/lib \ /Applications/Xcode.app/Contents/Developer/usr/bin/lldb ./target/debug/foo
b do_something
fails to find the symbol. Setting a breakpoint onrun_driver
and running and then trying to step intodo_something
is unable to work. Doing all of the above withpacked
split-debuginfo works as expected.Meta
rustc 1.53.0-nightly (74874a690 2021-03-30)
The text was updated successfully, but these errors were encountered: