Skip to content

Commit db7a250

Browse files
committed
Make cargo aware of dwp files.
When using -Csplit-debuginfo=packed on Linux, rustc will produce a dwp file. Unlike the dwo files, whose paths are embedded into the binary, there's no information in the binary to help a debugger locate a dwp file. By convention, the dwp file for <EXE> is given the name <EXE>.dwp and placed next to <EXE>. When cargo hardlinks the executable file rustc put in target/debug/deps into target/debug, it also needs to hardlink the dwp file along with it. Failing to do this prevents the debugger from finding the dwp file when the binary is executed from target/debug, as there's no way for the debugger to know to look in the deps subdirectory. The split_debuginfo option is passed down into file_types to make this possible. For cargo clean manual handling is added to match the other split_debuginfo files. bin_link_for_target also passes in None because it won't care about the dwp file.
1 parent 1cd6d38 commit db7a250

File tree

5 files changed

+63
-10
lines changed

5 files changed

+63
-10
lines changed

crates/cargo-test-support/src/lib.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -831,12 +831,17 @@ impl Execs {
831831
self
832832
}
833833

834+
pub fn enable_split_debuginfo_packed(&mut self) -> &mut Self {
835+
self.env("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO", "packed")
836+
.env("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO", "packed")
837+
.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed")
838+
.env("CARGO_PROFILE_BENCH_SPLIT_DEBUGINFO", "packed");
839+
self
840+
}
841+
834842
pub fn enable_mac_dsym(&mut self) -> &mut Self {
835843
if cfg!(target_os = "macos") {
836-
self.env("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO", "packed")
837-
.env("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO", "packed")
838-
.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed")
839-
.env("CARGO_PROFILE_BENCH_SPLIT_DEBUGINFO", "packed");
844+
return self.enable_split_debuginfo_packed();
840845
}
841846
self
842847
}

src/cargo/core/compiler/build_context/target_info.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ impl TargetInfo {
333333
crate_type: &CrateType,
334334
flavor: FileFlavor,
335335
target_triple: &str,
336+
split_debuginfo: Option<&str>,
336337
) -> CargoResult<Option<Vec<FileType>>> {
337338
let crate_type = if *crate_type == CrateType::Lib {
338339
CrateType::Rlib
@@ -462,6 +463,14 @@ impl TargetInfo {
462463
// preserved.
463464
should_replace_hyphens: true,
464465
})
466+
} else if split_debuginfo == Some("packed") {
467+
ret.push(FileType {
468+
suffix: format!("{}.dwp", suffix),
469+
prefix: prefix.clone(),
470+
flavor: FileFlavor::DebugInfo,
471+
crate_type: Some(crate_type.clone()),
472+
should_replace_hyphens: crate_type != CrateType::Bin,
473+
})
465474
}
466475
}
467476

@@ -494,11 +503,19 @@ impl TargetInfo {
494503
mode: CompileMode,
495504
target_kind: &TargetKind,
496505
target_triple: &str,
506+
split_debuginfo: Option<&str>,
497507
) -> CargoResult<(Vec<FileType>, Vec<CrateType>)> {
498508
match mode {
499-
CompileMode::Build => self.calc_rustc_outputs(target_kind, target_triple),
509+
CompileMode::Build => {
510+
self.calc_rustc_outputs(target_kind, target_triple, split_debuginfo)
511+
}
500512
CompileMode::Test | CompileMode::Bench => {
501-
match self.file_types(&CrateType::Bin, FileFlavor::Normal, target_triple)? {
513+
match self.file_types(
514+
&CrateType::Bin,
515+
FileFlavor::Normal,
516+
target_triple,
517+
split_debuginfo,
518+
)? {
502519
Some(fts) => Ok((fts, Vec::new())),
503520
None => Ok((Vec::new(), vec![CrateType::Bin])),
504521
}
@@ -517,6 +534,7 @@ impl TargetInfo {
517534
&self,
518535
target_kind: &TargetKind,
519536
target_triple: &str,
537+
split_debuginfo: Option<&str>,
520538
) -> CargoResult<(Vec<FileType>, Vec<CrateType>)> {
521539
let mut unsupported = Vec::new();
522540
let mut result = Vec::new();
@@ -527,7 +545,7 @@ impl TargetInfo {
527545
} else {
528546
FileFlavor::Normal
529547
};
530-
let file_types = self.file_types(crate_type, flavor, target_triple)?;
548+
let file_types = self.file_types(crate_type, flavor, target_triple, split_debuginfo)?;
531549
match file_types {
532550
Some(types) => {
533551
result.extend(types);

src/cargo/core/compiler/context/compilation_files.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
346346
CompileMode::Build,
347347
&TargetKind::Bin,
348348
bcx.target_data.short_name(&kind),
349+
None,
349350
)
350351
.expect("target must support `bin`");
351352

@@ -486,8 +487,12 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
486487

487488
let info = bcx.target_data.info(unit.kind);
488489
let triple = bcx.target_data.short_name(&unit.kind);
489-
let (file_types, unsupported) =
490-
info.rustc_outputs(unit.mode, unit.target.kind(), triple)?;
490+
let (file_types, unsupported) = info.rustc_outputs(
491+
unit.mode,
492+
unit.target.kind(),
493+
triple,
494+
unit.profile.split_debuginfo.as_deref(),
495+
)?;
491496
if file_types.is_empty() {
492497
if !unsupported.is_empty() {
493498
let unsupported_strs: Vec<_> = unsupported.iter().map(|ct| ct.as_str()).collect();

src/cargo/ops/cargo_clean.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
174174

175175
let (file_types, _unsupported) = target_data
176176
.info(*compile_kind)
177-
.rustc_outputs(mode, target.kind(), triple)?;
177+
.rustc_outputs(mode, target.kind(), triple, None)?;
178178
let (dir, uplift_dir) = match target.kind() {
179179
TargetKind::ExampleBin | TargetKind::ExampleLib(..) => {
180180
(layout.examples(), Some(layout.examples()))
@@ -203,6 +203,8 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
203203
rm_rf_glob(&split_debuginfo_obj, config, &mut progress)?;
204204
let split_debuginfo_dwo = dir_glob.join(format!("{}.*.dwo", crate_name));
205205
rm_rf_glob(&split_debuginfo_dwo, config, &mut progress)?;
206+
let split_debuginfo_dwp = dir_glob.join(format!("{}.*.dwp", crate_name));
207+
rm_rf_glob(&split_debuginfo_dwp, config, &mut progress)?;
206208

207209
// Remove the uplifted copy.
208210
if let Some(uplift_dir) = uplift_dir {

tests/testsuite/build.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5216,6 +5216,29 @@ fn uplift_pdb_of_bin_on_windows() {
52165216
assert!(!p.target_debug_dir().join("d.pdb").exists());
52175217
}
52185218

5219+
#[cargo_test]
5220+
#[cfg(target_os = "linux")]
5221+
fn uplift_dwp_of_bin_on_linux() {
5222+
let p = project()
5223+
.file("src/main.rs", "fn main() { panic!(); }")
5224+
.file("src/bin/b.rs", "fn main() { panic!(); }")
5225+
.file("src/bin/foo-bar.rs", "fn main() { panic!(); }")
5226+
.file("examples/c.rs", "fn main() { panic!(); }")
5227+
.file("tests/d.rs", "fn main() { panic!(); }")
5228+
.build();
5229+
5230+
p.cargo("build --bins --examples --tests")
5231+
.enable_split_debuginfo_packed()
5232+
.run();
5233+
assert!(p.target_debug_dir().join("foo.dwp").is_file());
5234+
assert!(p.target_debug_dir().join("b.dwp").is_file());
5235+
assert!(p.target_debug_dir().join("examples/c.dwp").exists());
5236+
assert!(p.target_debug_dir().join("foo-bar").is_file());
5237+
assert!(p.target_debug_dir().join("foo-bar.dwp").is_file());
5238+
assert!(!p.target_debug_dir().join("c.dwp").exists());
5239+
assert!(!p.target_debug_dir().join("d.dwp").exists());
5240+
}
5241+
52195242
// Ensure that `cargo build` chooses the correct profile for building
52205243
// targets based on filters (assuming `--profile` is not specified).
52215244
#[cargo_test]

0 commit comments

Comments
 (0)