Skip to content

Commit 7f2fc33

Browse files
committed
Auto merge of #115120 - icedrocket:ignore-strip-on-msvc, r=michaelwoerister
Ignore `-C strip` on MSVC tl;dr - Define `-Cstrip` to only ever affect the binary; no other build artifacts. This is necessary to improve cross-platform behavior consistency: if someone wanted debug information to be contained only in separate files on all platforms, they would set `-Cstrip=symbols` and `-Csplit-debuginfo=packed`, but this would result in no PDB files on MSVC. Resolves #114215
2 parents 290d792 + e82f46a commit 7f2fc33

File tree

4 files changed

+103
-57
lines changed

4 files changed

+103
-57
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+35-42
Original file line numberDiff line numberDiff line change
@@ -902,52 +902,45 @@ impl<'a> Linker for MsvcLinker<'a> {
902902
}
903903
}
904904

905-
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]) {
906-
match strip {
907-
Strip::None => {
908-
// This will cause the Microsoft linker to generate a PDB file
909-
// from the CodeView line tables in the object files.
910-
self.cmd.arg("/DEBUG");
911-
912-
// Default to emitting only the file name of the PDB file into
913-
// the binary instead of the full path. Emitting the full path
914-
// may leak private information (such as user names).
915-
// See https://github.com/rust-lang/rust/issues/87825.
916-
//
917-
// This default behavior can be overridden by explicitly passing
918-
// `-Clink-arg=/PDBALTPATH:...` to rustc.
919-
self.cmd.arg("/PDBALTPATH:%_PDB%");
920-
921-
// This will cause the Microsoft linker to embed .natvis info into the PDB file
922-
let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
923-
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
924-
for entry in natvis_dir {
925-
match entry {
926-
Ok(entry) => {
927-
let path = entry.path();
928-
if path.extension() == Some("natvis".as_ref()) {
929-
let mut arg = OsString::from("/NATVIS:");
930-
arg.push(path);
931-
self.cmd.arg(arg);
932-
}
933-
}
934-
Err(error) => {
935-
self.sess.dcx().emit_warn(errors::NoNatvisDirectory { error });
936-
}
905+
fn debuginfo(&mut self, _strip: Strip, natvis_debugger_visualizers: &[PathBuf]) {
906+
// This will cause the Microsoft linker to generate a PDB file
907+
// from the CodeView line tables in the object files.
908+
self.cmd.arg("/DEBUG");
909+
910+
// Default to emitting only the file name of the PDB file into
911+
// the binary instead of the full path. Emitting the full path
912+
// may leak private information (such as user names).
913+
// See https://github.com/rust-lang/rust/issues/87825.
914+
//
915+
// This default behavior can be overridden by explicitly passing
916+
// `-Clink-arg=/PDBALTPATH:...` to rustc.
917+
self.cmd.arg("/PDBALTPATH:%_PDB%");
918+
919+
// This will cause the Microsoft linker to embed .natvis info into the PDB file
920+
let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
921+
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
922+
for entry in natvis_dir {
923+
match entry {
924+
Ok(entry) => {
925+
let path = entry.path();
926+
if path.extension() == Some("natvis".as_ref()) {
927+
let mut arg = OsString::from("/NATVIS:");
928+
arg.push(path);
929+
self.cmd.arg(arg);
937930
}
938931
}
939-
}
940-
941-
// This will cause the Microsoft linker to embed .natvis info for all crates into the PDB file
942-
for path in natvis_debugger_visualizers {
943-
let mut arg = OsString::from("/NATVIS:");
944-
arg.push(path);
945-
self.cmd.arg(arg);
932+
Err(error) => {
933+
self.sess.dcx().emit_warn(errors::NoNatvisDirectory { error });
934+
}
946935
}
947936
}
948-
Strip::Debuginfo | Strip::Symbols => {
949-
self.cmd.arg("/DEBUG:NONE");
950-
}
937+
}
938+
939+
// This will cause the Microsoft linker to embed .natvis info for all crates into the PDB file
940+
for path in natvis_debugger_visualizers {
941+
let mut arg = OsString::from("/NATVIS:");
942+
arg.push(path);
943+
self.cmd.arg(arg);
951944
}
952945
}
953946

src/doc/rustc/src/codegen-options/index.md

+16-15
Original file line numberDiff line numberDiff line change
@@ -568,22 +568,23 @@ data from binaries during linking.
568568

569569
Supported values for this option are:
570570

571-
- `none` - debuginfo and symbols (if they exist) are copied to the produced
572-
binary or separate files depending on the target (e.g. `.pdb` files in case
573-
of MSVC).
571+
- `none` - debuginfo and symbols are not modified.
574572
- `debuginfo` - debuginfo sections and debuginfo symbols from the symbol table
575-
section are stripped at link time and are not copied to the produced binary
576-
or separate files. This should leave backtraces mostly-intact but may make
577-
using a debugger like gdb or lldb ineffectual.
578-
- `symbols` - same as `debuginfo`, but the rest of the symbol table section is stripped as well,
579-
depending on platform support. On platforms which depend on this symbol table for backtraces,
580-
profiling, and similar, this can affect them so negatively as to make the trace incomprehensible.
581-
Programs which may be combined with others, such as CLI pipelines and developer tooling,
582-
or even anything which wants crash-reporting, should usually avoid `-Cstrip=symbols`.
583-
584-
Note that, at any level, removing debuginfo only necessarily impacts "friendly" introspection.
585-
`-Cstrip` cannot be relied on as a meaningful security or obfuscation measure, as disassemblers
586-
and decompilers can extract considerable information even in the absence of symbols.
573+
section are stripped at link time and are not copied to the produced binary.
574+
This should leave backtraces mostly-intact but may make using a debugger like
575+
gdb or lldb ineffectual. Prior to 1.79, this unintentionally disabled the
576+
generation of `*.pdb` files on MSVC, resulting in the absence of symbols.
577+
- `symbols` - same as `debuginfo`, but the rest of the symbol table section is
578+
stripped as well, depending on platform support. On platforms which depend on
579+
this symbol table for backtraces, profiling, and similar, this can affect
580+
them so negatively as to make the trace incomprehensible. Programs which may
581+
be combined with others, such as CLI pipelines and developer tooling, or even
582+
anything which wants crash-reporting, should usually avoid `-Cstrip=symbols`.
583+
584+
Note that, at any level, removing debuginfo only necessarily impacts "friendly"
585+
introspection. `-Cstrip` cannot be relied on as a meaningful security or
586+
obfuscation measure, as disassemblers and decompilers can extract considerable
587+
information even in the absence of symbols.
587588

588589
## symbol-mangling-version
589590

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ compile-flags: -C strip=debuginfo
2+
//@ only-msvc
3+
//@ run-pass
4+
5+
use std::path::Path;
6+
7+
pub fn is_related_pdb<P: AsRef<Path>>(path: &P, exe: &P) -> bool {
8+
let (exe, path) = (exe.as_ref(), path.as_ref());
9+
10+
path.extension()
11+
.map(|x| x.to_ascii_lowercase())
12+
.is_some_and(|x| x == "pdb")
13+
&& path.file_stem() == exe.file_stem()
14+
}
15+
16+
pub fn main() {
17+
let curr_exe = std::env::current_exe().unwrap();
18+
let curr_dir = curr_exe.parent().unwrap();
19+
20+
let entries = std::fs::read_dir(curr_dir).unwrap();
21+
22+
assert!(entries
23+
.map_while(|x| x.ok())
24+
.find(|x| is_related_pdb(&x.path(), &curr_exe))
25+
.is_some());
26+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ compile-flags: -C strip=symbols
2+
//@ only-msvc
3+
//@ run-pass
4+
5+
use std::path::Path;
6+
7+
pub fn is_related_pdb<P: AsRef<Path>>(path: &P, exe: &P) -> bool {
8+
let (exe, path) = (exe.as_ref(), path.as_ref());
9+
10+
path.extension()
11+
.map(|x| x.to_ascii_lowercase())
12+
.is_some_and(|x| x == "pdb")
13+
&& path.file_stem() == exe.file_stem()
14+
}
15+
16+
pub fn main() {
17+
let curr_exe = std::env::current_exe().unwrap();
18+
let curr_dir = curr_exe.parent().unwrap();
19+
20+
let entries = std::fs::read_dir(curr_dir).unwrap();
21+
22+
assert!(entries
23+
.map_while(|x| x.ok())
24+
.find(|x| is_related_pdb(&x.path(), &curr_exe))
25+
.is_some());
26+
}

0 commit comments

Comments
 (0)