Skip to content

Commit

Permalink
Auto merge of #118518 - weihanglo:trim-paths-macos, r=<try>
Browse files Browse the repository at this point in the history
fix(trim-paths): trim `SO` and `DW_AT_comp_dir` symbols for root DI node

This is one way to fix <#117652>.

## The issue

When `--remap-path-scope=object` is specified, user expect that there is
no local path embedded in final executables. Under `object` scope, the
current implementation only remap debug symbols if debug info is
splitted into its own file. In other words, when
`split-debuginfo=packed|unpacked` is set, rustc assumes there is no
embedded path in the final executable needing to be remapped.

However, this doesn't work.

* On Linux, the root `DW_AT_comp_dir` of a compile unit seems to go into the binary executables.
* On macOS, `SO` symbols are embedded in binary executables and libraries regardless a split-debuginfo file is built. Each `SO` symbol contains a path to the root source file of a debug info compile unit.

## The approach

Path of working directory in the root DI node seems to be embedded in
executables. Hence, we trim them when the scope of `unsplit-debuginfo`
is present, as if it is kinda a "unsplit" debuginfo.

## Unresolved issue

* Not sure where to add more test to consolidate it.
* Haven't investigate if we should apply the same logic to cranelift [here](https://github.com/rust-lang/rust/blob/64d7e0d0b61c460fbc882ae37c0f236756dd9c39/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs#L68-L80).
* Not sure if there is any other consequence doing this, but AFAIK debugging still works on macOS and Linux  with `profile.dev.trim-paths="object"` fairly (with some extra tweaks in cargo).
  • Loading branch information
bors committed Dec 8, 2023
2 parents 2b399b5 + 4fa22f1 commit 4311f2e
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 31 deletions.
17 changes: 15 additions & 2 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,22 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
let producer = format!("clang LLVM ({rustc_producer})");

use rustc_session::RemapFileNameExt;
let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
let work_dir = tcx.sess.opts.working_dir.for_codegen(tcx.sess).to_string_lossy();
debug!(?name_in_debuginfo, "build_compile_unit_di_node");

// Path of working directory in the root DI node seems to be embedded in
// executables. Hence, we trim them when the scope of `unsplit-debuginfo`
// is present, as if it is kinda a "unsplit" debuginfo.
use rustc_session::config::RemapPathScopeComponents;
use rustc_session::RemapFileNameExt;
let work_dir = tcx
.sess
.opts
.working_dir
.for_scope(tcx.sess, RemapPathScopeComponents::UNSPLIT_DEBUGINFO)
.to_string_lossy();
debug!(?work_dir, "build_compile_unit_di_node");

let flags = "\0";
let output_filenames = tcx.output_filenames(());
let split_name = if tcx.sess.target_can_use_split_dwarf() {
Expand Down
142 changes: 113 additions & 29 deletions tests/run-make/split-debuginfo/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# ignore-cross-compile
include ../tools.mk

export HERE := $(shell pwd)

all: off packed unpacked

ifeq ($(UNAME),Darwin)
Expand All @@ -11,23 +13,77 @@ off:
[ ! -d $(TMPDIR)/foo.dSYM ]

# Packed by default, but only if debuginfo is requested
packed:
rm -rf $(TMPDIR)/*.dSYM
$(RUSTC) foo.rs
[ ! -d $(TMPDIR)/foo.dSYM ]
rm -rf $(TMPDIR)/*.dSYM
$(RUSTC) foo.rs -g
packed: packed-remapped-scope packed-remapped-wrong-scope

# - Debuginfo in binary file
# - `.o` deleted
# - `.dSYM` present
# - in binary, paths from `N_SO` (source files) and `N_OSO` (object files) shouldn be remapped
packed-remapped-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
-Z remap-path-scope=object foo.rs -g
ls $(TMPDIR)/*.o && exit 1 || exit 0
[ -d $(TMPDIR)/foo.dSYM ]
rm -rf $(TMPDIR)/*.dSYM
$(RUSTC) foo.rs -g -C split-debuginfo=packed
# As of 2023-12, `OSO` should be the only thing that cannot be trimmed. See rust-lang/rust#116948
dsymutil -s $(TMPDIR)/foo | grep $(TMPDIR) || exit 1 # expected: `grep $(TMPDIR)` to exit 1
dsymutil -s $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
rm -rf $(TMPDIR)/foo.dSYM
rm $(TMPDIR)/$(call BIN,foo)

# - Debuginfo in binary file
# - `.o` deleted
# - `.dSYM` present
# - in binary, paths from `N_SO` (source files) and `N_OSO` (object files) shouldn't be remapped
packed-remapped-wrong-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
-Z remap-path-scope=macro foo.rs -g
ls $(TMPDIR)/*.o && exit 1 || exit 0
[ -d $(TMPDIR)/foo.dSYM ]
rm -rf $(TMPDIR)/*.dSYM
dsymutil -s $(TMPDIR)/foo | grep 'N_OSO' | grep $(TMPDIR) || exit 1
dsymutil -s $(TMPDIR)/foo | grep 'N_SO' | grep $(HERE) || exit 1
rm -rf $(TMPDIR)/foo.dSYM
rm $(TMPDIR)/$(call BIN,foo)

# Object files are preserved with unpacked and `dsymutil` isn't run
unpacked:
$(RUSTC) foo.rs -g -C split-debuginfo=unpacked
unpacked: unpacked-remapped-scope unpacked-remapped-wrong-scope

# - Debuginfo in object files
# - `.o` present
# - `.dSYM` never created
# - in binary, paths from `N_SO` (source files) and `N_OSO` (object files) should be remapped
unpacked-remapped-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
-Z remap-path-scope=object foo.rs -g
ls $(TMPDIR)/*.o
[ ! -d $(TMPDIR)/foo.dSYM ]
# As of 2023-12, `OSO` should be the only thing that cannot be trimmed. See rust-lang/rust#116948
dsymutil -s $(TMPDIR)/foo | grep $(TMPDIR) || exit 1 # expected: `grep $(TMPDIR)` to exit 1
dsymutil -s $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
rm $(TMPDIR)/*.o
rm $(TMPDIR)/$(call BIN,foo)

# - Debuginfo in object files
# - `.o` present,
# - `.dSYM` never created
# - in binary, paths from `N_SO` (source files) and `N_OSO` (object files) shouldn't be remapped
unpacked-remapped-wrong-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
-Z remap-path-scope=macro foo.rs -g
ls $(TMPDIR)/*.o
[ ! -d $(TMPDIR)/foo.dSYM ]
dsymutil -s $(TMPDIR)/foo | grep 'N_OSO' | (grep $(TMPDIR)) || exit 1
dsymutil -s $(TMPDIR)/foo | grep 'N_SO' | (grep $(HERE)) || exit 1
rm $(TMPDIR)/*.o
rm $(TMPDIR)/$(call BIN,foo)

else
ifdef IS_WINDOWS
# Windows only supports packed debuginfo - nothing to test.
Expand Down Expand Up @@ -113,8 +169,12 @@ packed-remapped: packed-remapped-split packed-remapped-single packed-remapped-sc
# - `.dwp` present
packed-remapped-split:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
-Z split-dwarf-kind=split \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
foo.rs -g
readelf -wi $(TMPDIR)/foo | (! grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm $(TMPDIR)/foo.dwp
Expand All @@ -127,8 +187,12 @@ packed-remapped-split:
# - `.dwp` present
packed-remapped-single:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
-Z split-dwarf-kind=single \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
foo.rs -g
readelf -wi $(TMPDIR)/foo | (! grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm $(TMPDIR)/foo.dwp
Expand All @@ -141,9 +205,12 @@ packed-remapped-single:
# - `.dwp` present
packed-remapped-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \
-Z remap-path-scope=split-debuginfo-path foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
-Z split-dwarf-kind=single \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
-Z remap-path-scope=object foo.rs -g
readelf -wi $(TMPDIR)/foo | (! grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm $(TMPDIR)/foo.dwp
Expand All @@ -156,9 +223,12 @@ packed-remapped-scope:
# - `.dwp` present
packed-remapped-wrong-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \
-Z split-dwarf-kind=single \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(TMPDIR)=/b \
-Z remap-path-scope=macro foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | (grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | grep $(HERE) || exit 1
ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm $(TMPDIR)/foo.dwp
Expand Down Expand Up @@ -269,8 +339,12 @@ unpacked-remapped: unpacked-remapped-split unpacked-remapped-single unpacked-rem
# - `.dwp` never created
unpacked-remapped-split:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
-Z split-dwarf-kind=split \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
foo.rs -g
readelf -wi $(TMPDIR)/foo | (! grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
ls $(TMPDIR)/*.o && exit 1 || exit 0
rm $(TMPDIR)/*.dwo
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
Expand All @@ -283,8 +357,12 @@ unpacked-remapped-split:
# - `.dwp` never created
unpacked-remapped-single:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
-Z split-dwarf-kind=single \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
foo.rs -g
readelf -wi $(TMPDIR)/foo | (! grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
rm $(TMPDIR)/*.o
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
Expand All @@ -297,9 +375,12 @@ unpacked-remapped-single:
# - `.dwp` never created
unpacked-remapped-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \
-Z remap-path-scope=split-debuginfo-path foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
-Z split-dwarf-kind=single \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
-Z remap-path-scope=object foo.rs -g
readelf -wi $(TMPDIR)/foo | (! grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | (! grep $(HERE)) || exit 1
rm $(TMPDIR)/*.o
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
Expand All @@ -312,9 +393,12 @@ unpacked-remapped-scope:
# - `.dwp` never created
unpacked-remapped-wrong-scope:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \
-Z split-dwarf-kind=single \
--remap-path-prefix $(TMPDIR)=/a \
--remap-path-prefix $(HERE)=/b \
-Z remap-path-scope=macro foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (grep $(TMPDIR)) || exit 1
readelf -wi $(TMPDIR)/foo | grep $(TMPDIR) || exit 1
readelf -wi $(TMPDIR)/foo | grep $(HERE) || exit 1
rm $(TMPDIR)/*.o
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
Expand Down

0 comments on commit 4311f2e

Please sign in to comment.