about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-15 14:14:34 +0000
committerbors <bors@rust-lang.org>2024-03-15 14:14:34 +0000
commitc5b571310dc60c6a58c6505cce2fb7e2f3f9aa68 (patch)
tree628b99c5d1b6676ea7eba0db849dcafaee26612d
parentaccc516128b21e960b1a7af45393e9acdd184890 (diff)
parent0a094bae28a00117b99262621ff22876796d2885 (diff)
downloadrust-c5b571310dc60c6a58c6505cce2fb7e2f3f9aa68.tar.gz
rust-c5b571310dc60c6a58c6505cce2fb7e2f3f9aa68.zip
Auto merge of #121297 - michaelwoerister:set-pdb-alt-path, r=wesleywiser
link.exe: Don't embed full path to PDB file in binary.

This PR makes `rustc` unconditionally pass `/PDBALTPATH:%_PDB%` to MSVC-style linkers, causing the linker to only embed the filename of the PDB in the binary instead of the full path. This will help implement the [trim-paths RFC](https://github.com/rust-lang/rust/issues/111540) for `*-msvc` targets.

Passing `/PDBALTPATH:%_PDB%` to the linker is already done by many projects that need reproducible builds and [debugger's should still be able to find the PDB](https://learn.microsoft.com/cpp/build/reference/pdbpath) if it is in the same directory as the binary.

r? `@ghost`

Fixes https://github.com/rust-lang/rust/issues/87825
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs9
-rw-r--r--tests/run-make/pdb-alt-path/Makefile20
-rw-r--r--tests/run-make/pdb-alt-path/main.rs24
3 files changed, 53 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index bb23e21b2a2..f5640ea26bc 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -929,6 +929,15 @@ impl<'a> Linker for MsvcLinker<'a> {
                 // from the CodeView line tables in the object files.
                 self.cmd.arg("/DEBUG");
 
+                // Default to emitting only the file name of the PDB file into
+                // the binary instead of the full path. Emitting the full path
+                // may leak private information (such as user names).
+                // See https://github.com/rust-lang/rust/issues/87825.
+                //
+                // This default behavior can be overridden by explicitly passing
+                // `-Clink-arg=/PDBALTPATH:...` to rustc.
+                self.cmd.arg("/PDBALTPATH:%_PDB%");
+
                 // This will cause the Microsoft linker to embed .natvis info into the PDB file
                 let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
                 if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
diff --git a/tests/run-make/pdb-alt-path/Makefile b/tests/run-make/pdb-alt-path/Makefile
new file mode 100644
index 00000000000..7a0ae3bf2ef
--- /dev/null
+++ b/tests/run-make/pdb-alt-path/Makefile
@@ -0,0 +1,20 @@
+include ../tools.mk
+
+# only-windows-msvc
+
+all:
+	# Test that we don't have the full path to the PDB file in the binary
+	$(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Cforce-frame-pointers
+	$(CGREP) "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe
+	$(CGREP) -v "\\my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe
+
+	# Test that backtraces still can find debuginfo by checking that they contain symbol names and
+	# source locations.
+	$(TMPDIR)/my_crate_name.exe &> $(TMPDIR)/backtrace.txt
+	$(CGREP) "my_crate_name::fn_in_backtrace" < $(TMPDIR)/backtrace.txt
+	$(CGREP) "main.rs:15" < $(TMPDIR)/backtrace.txt
+
+	# Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected
+	$(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Clink-arg=/PDBALTPATH:abcdefg.pdb -Cforce-frame-pointers
+	$(CGREP) "abcdefg.pdb" < $(TMPDIR)/my_crate_name.exe
+	$(CGREP) -v "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe
diff --git a/tests/run-make/pdb-alt-path/main.rs b/tests/run-make/pdb-alt-path/main.rs
new file mode 100644
index 00000000000..d38d540fbc2
--- /dev/null
+++ b/tests/run-make/pdb-alt-path/main.rs
@@ -0,0 +1,24 @@
+// The various #[inline(never)] annotations and std::hint::black_box calls are
+// an attempt to make unwinding as non-flaky as possible on i686-pc-windows-msvc.
+
+#[inline(never)]
+fn generate_backtrace(x: &u32) {
+    std::hint::black_box(x);
+    let bt = std::backtrace::Backtrace::force_capture();
+    println!("{}", bt);
+    std::hint::black_box(x);
+}
+
+#[inline(never)]
+fn fn_in_backtrace(x: &u32) {
+    std::hint::black_box(x);
+    generate_backtrace(x);
+    std::hint::black_box(x);
+}
+
+fn main() {
+    let x = &41;
+    std::hint::black_box(x);
+    fn_in_backtrace(x);
+    std::hint::black_box(x);
+}