Skip to content
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

Debug info is broken on macOS when using --remap-path-prefix #132143

Open
csmulhern opened this issue Oct 25, 2024 · 5 comments
Open

Debug info is broken on macOS when using --remap-path-prefix #132143

csmulhern opened this issue Oct 25, 2024 · 5 comments
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) A-path-remapping Area: path remapping, --remap-path-prefix, --remap-cwd-prefix, --remap-diagnostics-scope etc. C-bug Category: This is a bug. O-apple Operating system: Apple (macOS, iOS, tvOS, visionOS, watchOS) O-macos Operating system: macOS T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@csmulhern
Copy link

This can be easily reproduced with a simple program.

// main.rs
fn main() {
    println!("Hello, world!");
}

Without --remap-path-prefix, building with unpacked debug info:

rustc main.rs --codegen=debuginfo=2 --codegen=split-debuginfo=unpacked

Results in a binary that has an OSO entry pointing to the object file containing the debug info:

> nm -pa main | rg OSO
0000000000000000 - 00 0001   OSO /Users/cameron/Desktop/broken/main.main.7c41ea6d61ccd5c8-cgu.0.rcgu.o
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libstd-b0083070c892a1db.rlib(std-b0083070c892a1db.std.1bb08b5702199c76-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libpanic_unwind-8282820217d7b362.rlib(panic_unwind-8282820217d7b362.panic_unwind.edd611859befea2b-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libmemchr-350512940f04084a.rlib(memchr-350512940f04084a.memchr.163a0d7c2b1b5170-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_demangle-e1d006f163566466.rlib(rustc_demangle-e1d006f163566466.rustc_demangle.763a0c92458f345-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/liballoc-edb678dd3e28691a.rlib(alloc-edb678dd3e28691a.alloc.7c7540ab8626f01a-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcore-2447397acf63b01e.rlib(core-2447397acf63b01e.core.5213bbcd403abe9e-cgu.0.rcgu.o)

With --remap-path-prefix:

rustc main.rs --codegen=debuginfo=2 --codegen=split-debuginfo=unpacked --remap-path-prefix=/Users/cameron/Desktop/broken=

Results in a binary that is missing OSO entries for the remapped object files:

> nm -pa main | rg OSO
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libstd-b0083070c892a1db.rlib(std-b0083070c892a1db.std.1bb08b5702199c76-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libpanic_unwind-8282820217d7b362.rlib(panic_unwind-8282820217d7b362.panic_unwind.edd611859befea2b-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libmemchr-350512940f04084a.rlib(memchr-350512940f04084a.memchr.163a0d7c2b1b5170-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_demangle-e1d006f163566466.rlib(rustc_demangle-e1d006f163566466.rustc_demangle.763a0c92458f345-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/liballoc-edb678dd3e28691a.rlib(alloc-edb678dd3e28691a.alloc.7c7540ab8626f01a-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcore-2447397acf63b01e.rlib(core-2447397acf63b01e.core.5213bbcd403abe9e-cgu.0.rcgu.o)

Note how the first OSO entry from the first command is missing from the second:

0000000000000000 - 00 0001   OSO /Users/cameron/Desktop/broken/main.main.7c41ea6d61ccd5c8-cgu.0.rcgu.o

I believe the same underlying issue prevents --split-debuginfo=packed from generating a dSYM containing debug info for the object files containing the remapped path prefix, as I believe dsymutil is just using the OSO entries to create a self contained set of DWARF debug info.

Packed debug info without remapping:

rustc main.rs --codegen=debuginfo=2 --codegen=split-debuginfo=packed

Results in a complete dSYM:

> dwarfdump main.dSYM | rg "main.rs" -B 8
main.dSYM/Contents/Resources/DWARF/main:	file format Mach-O arm64

.debug_info contents:
0x00000000: Compile Unit: length = 0x0000091b, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000091f)

0x0000000b: DW_TAG_compile_unit
              DW_AT_producer	("clang LLVM (rustc version 1.82.0 (f6e511eec 2024-10-15))")
              DW_AT_language	(DW_LANG_Rust)
              DW_AT_name	("main.rs/@/main.4b21619d1e36c66a-cgu.0")
--
                DW_AT_name	("main")

0x000008d6:     DW_TAG_subprogram
                  DW_AT_low_pc	(0x0000000100001720)
                  DW_AT_high_pc	(0x0000000100001754)
                  DW_AT_frame_base	(DW_OP_reg29 W29)
                  DW_AT_linkage_name	("_ZN4main4main17h0cc9ac8d6b33b55fE")
                  DW_AT_name	("main")
                  DW_AT_decl_file	("/Users/cameron/Desktop/broken/main.rs")

Whereas the remapped version:

rustc main.rs --codegen=debuginfo=2 --codegen=split-debuginfo=packed --remap-path-prefix=/Users/cameron/Desktop/broken=

Does not:

> dwarfdump main.dSYM | rg "main.rs" -B 8

All these issues are reproducible on a recent nightly (rustc version 1.84.0-nightly (a93c1718c 2024-10-24)).

@csmulhern csmulhern added the C-bug Category: This is a bug. label Oct 25, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Oct 25, 2024
@saethlin saethlin added O-macos Operating system: macOS A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. O-apple Operating system: Apple (macOS, iOS, tvOS, visionOS, watchOS) A-path-remapping Area: path remapping, --remap-path-prefix, --remap-cwd-prefix, --remap-diagnostics-scope etc. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 25, 2024
@csmulhern
Copy link
Author

This is just a guess, but I suspect the issue is to do with the fact that remapped paths become relative paths, whereas OSO paths seem to always be absolute.

For example, if I use the oso_prefix linker argument to do path remapping specifically for the OSO stabs, the path becomes the relative path rooted at /.

rustc main.rs --codegen=debuginfo=2 --codegen=split-debuginfo=unpacked --codegen=link-args=-Wl,-oso_prefix,/Users/cameron/Desktop/broken
> nm -pa main | rg OSO
0000000000000000 - 00 0001   OSO /main.main.4b21619d1e36c66a-cgu.0.rcgu.o
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libstd-0b4a354a5d882f18.rlib(std-0b4a354a5d882f18.std.d8d90c69e022292b-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libpanic_unwind-00e89274fccf37d9.rlib(panic_unwind-00e89274fccf37d9.panic_unwind.ea3026af965941fa-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libmemchr-726032628236814d.rlib(memchr-726032628236814d.memchr.5ae0b6d692968ecf-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/liballoc-a7504b44dda8a2a3.rlib(alloc-a7504b44dda8a2a3.alloc.764fc8c78a1bb3e1-cgu.0.rcgu.o)
0000000000000000 - 00 0001   OSO /Users/cameron/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcore-a17e2a568e77fc15.rlib(core-a17e2a568e77fc15.core.fafc87a594706398-cgu.0.rcgu.o)

@csmulhern
Copy link
Author

After a little more investigation, I'm wondering if the fact that DW_AT_comp_dir is missing when --remap-path-prefix is used is responsible for this. It's possible ld-prime is only emitting OSO stabs when both DW_AT_name and DW_AT_comp_dir are specified in the debug info. I don't have access to an old version of macOS using ld64 to see if the same issue is present there as well.

I will file feedback with Apple and hopefully ld-prime can be updated to support this. A mitigation on the rustc side would be to not remap paths in DWARF debug info on macOS, and rely on the oso_prefix linker option for path remapping instead.

@weihanglo
Copy link
Member

The broken debuginfo is kinda expected? Without any -Zremap-path-scope specified, --remap-path-prefix remaps everything for you to get fully sanitized artifacts.

@csmulhern
Copy link
Author

In this case, I want the scope to include debuginfo. The --remap-path-prefix should be applied to the OSO stabs, resulting in relative paths instead (/Users/cameron/Desktop/broken/main.main.7c41ea6d61ccd5c8-cgu.0.rcgu.o -> main.main.4b21619d1e36c66a-cgu.0.rcgu.o).

The problem appears to be that when DW_AT_name is a relative path and DW_AT_comp_dir is absent, then the ld linker just throws out the OSO stab, instead of doing what oso_prefix does and having a "relative" path by just rooting the relative path at "/" (because I'm guessing OSO stabs must start with /).

I guess a workaround would be to use -Zremap-path-scope to prevent --remap-path-prefix from applying to debuginfo, and then relying on the oso_prefix linker flag to relative these paths, but that won't help with stripping machine-specific paths from the intermediate object files.

Another workaround would be to use something like /proc/self/cwd as the path prefix. I think Bazel does something like this. But there are many places in the output artifacts where this wouldn't be necessary, and a relative path would be preferred. It doesn't seem like there'd be a way to apply this to only debuginfo using -Zremap-path-scope and --remap-path-prefix (e.g. --remap-path-prefix=/Users/cameron/Desktop/broken= -Zremap-path-scope=macro,diagnostics,object --remap-path-prefix=/Users/cameron/Desktop/broken=/proc/self/cwd -Zremap-path-scope=debuginfo.

It seems like either / both:

  1. Out of the box rustc should do something here so users can use --remap-path-prefix on macOS and not break debug info. E.g. set DW_AT_comp_dir to some placeholder value (e.g. / or /proc/self/cwd).

  2. There should be a way to use --remap-path-scope on macOS to relativize paths in the output artifacts, including debug info, while being able to customize the prefix remapping for the same prefix based on scope.

@weihanglo
Copy link
Member

when DW_AT_name is a relative path and DW_AT_comp_dir is absent, then the ld linker just throws out the OSO stab,

Have you managed to confirm that is true with Apple?

[…] and then relying on the oso_prefix

Yes that is possibly the cleverest way.

IIRC debugger is not intended to work with full sanitization done by --remap-path-prefix, and neither split debuginfo is. That said, it is possible to change the behavior. Here are some past discussions:

cc @Urgau (summon you because I am forgetting stuff again…)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) A-path-remapping Area: path remapping, --remap-path-prefix, --remap-cwd-prefix, --remap-diagnostics-scope etc. C-bug Category: This is a bug. O-apple Operating system: Apple (macOS, iOS, tvOS, visionOS, watchOS) O-macos Operating system: macOS T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants