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
This commit is contained in:
bors 2024-04-22 12:05:39 +00:00
commit 7f2fc33da6
4 changed files with 100 additions and 54 deletions

View File

@ -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");
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%");
// 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 });
}
// 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 });
}
}
}
}
// 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);
}
}
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);
}
}

View File

@ -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`.
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.
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

View File

@ -0,0 +1,26 @@
//@ compile-flags: -C strip=debuginfo
//@ only-msvc
//@ run-pass
use std::path::Path;
pub fn is_related_pdb<P: AsRef<Path>>(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());
}

View File

@ -0,0 +1,26 @@
//@ compile-flags: -C strip=symbols
//@ only-msvc
//@ run-pass
use std::path::Path;
pub fn is_related_pdb<P: AsRef<Path>>(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());
}