diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index fad6f4394418a..85fcc4f4f4046 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -902,52 +902,45 @@ impl<'a> Linker for MsvcLinker<'a> { } } - fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]) { - match strip { - Strip::None => { - // This will cause the Microsoft linker to generate a PDB file - // 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) { - for entry in natvis_dir { - match entry { - Ok(entry) => { - let path = entry.path(); - if path.extension() == Some("natvis".as_ref()) { - let mut arg = OsString::from("/NATVIS:"); - arg.push(path); - self.cmd.arg(arg); - } - } - Err(error) => { - self.sess.dcx().emit_warn(errors::NoNatvisDirectory { error }); - } + fn debuginfo(&mut self, _strip: Strip, natvis_debugger_visualizers: &[PathBuf]) { + // This will cause the Microsoft linker to generate a PDB file + // 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) { + for entry in natvis_dir { + match entry { + Ok(entry) => { + let path = entry.path(); + if path.extension() == Some("natvis".as_ref()) { + let mut arg = OsString::from("/NATVIS:"); + arg.push(path); + self.cmd.arg(arg); } } - } - - // This will cause the Microsoft linker to embed .natvis info for all crates into the PDB file - for path in natvis_debugger_visualizers { - let mut arg = OsString::from("/NATVIS:"); - arg.push(path); - self.cmd.arg(arg); + Err(error) => { + self.sess.dcx().emit_warn(errors::NoNatvisDirectory { error }); + } } } - Strip::Debuginfo | Strip::Symbols => { - self.cmd.arg("/DEBUG:NONE"); - } + } + + // This will cause the Microsoft linker to embed .natvis info for all crates into the PDB file + for path in natvis_debugger_visualizers { + let mut arg = OsString::from("/NATVIS:"); + arg.push(path); + self.cmd.arg(arg); } } diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 35bf2c27ff1b4..673ff12b5ceb0 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -568,22 +568,23 @@ data from binaries during linking. Supported values for this option are: -- `none` - debuginfo and symbols (if they exist) are copied to the produced - binary or separate files depending on the target (e.g. `.pdb` files in case - of MSVC). +- `none` - debuginfo and symbols are not modified. - `debuginfo` - debuginfo sections and debuginfo symbols from the symbol table - section are stripped at link time and are not copied to the produced binary - or separate files. This should leave backtraces mostly-intact but may make - using a debugger like gdb or lldb ineffectual. -- `symbols` - same as `debuginfo`, but the rest of the symbol table section is stripped as well, - depending on platform support. On platforms which depend on this symbol table for backtraces, - profiling, and similar, this can affect them so negatively as to make the trace incomprehensible. - Programs which may be combined with others, such as CLI pipelines and developer tooling, - or even anything which wants crash-reporting, should usually avoid `-Cstrip=symbols`. - -Note that, at any level, removing debuginfo only necessarily impacts "friendly" introspection. -`-Cstrip` cannot be relied on as a meaningful security or obfuscation measure, as disassemblers -and decompilers can extract considerable information even in the absence of symbols. + section are stripped at link time and are not copied to the produced binary. + This should leave backtraces mostly-intact but may make using a debugger like + gdb or lldb ineffectual. Prior to 1.79, this unintentionally disabled the + generation of `*.pdb` files on MSVC, resulting in the absence of symbols. +- `symbols` - same as `debuginfo`, but the rest of the symbol table section is + stripped as well, depending on platform support. On platforms which depend on + this symbol table for backtraces, profiling, and similar, this can affect + them so negatively as to make the trace incomprehensible. Programs which may + be combined with others, such as CLI pipelines and developer tooling, or even + anything which wants crash-reporting, should usually avoid `-Cstrip=symbols`. + +Note that, at any level, removing debuginfo only necessarily impacts "friendly" +introspection. `-Cstrip` cannot be relied on as a meaningful security or +obfuscation measure, as disassemblers and decompilers can extract considerable +information even in the absence of symbols. ## symbol-mangling-version diff --git a/tests/ui/debuginfo/msvc-strip-debuginfo.rs b/tests/ui/debuginfo/msvc-strip-debuginfo.rs new file mode 100644 index 0000000000000..d5f516eefe2a6 --- /dev/null +++ b/tests/ui/debuginfo/msvc-strip-debuginfo.rs @@ -0,0 +1,26 @@ +//@ compile-flags: -C strip=debuginfo +//@ only-msvc +//@ run-pass + +use std::path::Path; + +pub fn is_related_pdb>(path: &P, exe: &P) -> bool { + let (exe, path) = (exe.as_ref(), path.as_ref()); + + path.extension() + .map(|x| x.to_ascii_lowercase()) + .is_some_and(|x| x == "pdb") + && path.file_stem() == exe.file_stem() +} + +pub fn main() { + let curr_exe = std::env::current_exe().unwrap(); + let curr_dir = curr_exe.parent().unwrap(); + + let entries = std::fs::read_dir(curr_dir).unwrap(); + + assert!(entries + .map_while(|x| x.ok()) + .find(|x| is_related_pdb(&x.path(), &curr_exe)) + .is_some()); +} diff --git a/tests/ui/debuginfo/msvc-strip-symbols.rs b/tests/ui/debuginfo/msvc-strip-symbols.rs new file mode 100644 index 0000000000000..198c9496cb494 --- /dev/null +++ b/tests/ui/debuginfo/msvc-strip-symbols.rs @@ -0,0 +1,26 @@ +//@ compile-flags: -C strip=symbols +//@ only-msvc +//@ run-pass + +use std::path::Path; + +pub fn is_related_pdb>(path: &P, exe: &P) -> bool { + let (exe, path) = (exe.as_ref(), path.as_ref()); + + path.extension() + .map(|x| x.to_ascii_lowercase()) + .is_some_and(|x| x == "pdb") + && path.file_stem() == exe.file_stem() +} + +pub fn main() { + let curr_exe = std::env::current_exe().unwrap(); + let curr_dir = curr_exe.parent().unwrap(); + + let entries = std::fs::read_dir(curr_dir).unwrap(); + + assert!(entries + .map_while(|x| x.ok()) + .find(|x| is_related_pdb(&x.path(), &curr_exe)) + .is_some()); +}