From 1230a76fc41eae6099c1b59332b2e6abd6d4c21f Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Thu, 12 Jan 2023 17:43:26 -0800 Subject: [PATCH] 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 is given the name .dwp and placed next to . 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. --- .../compiler/build_context/target_info.rs | 24 ++++++++++++++++--- .../compiler/context/compilation_files.rs | 9 +++++-- src/cargo/ops/cargo_clean.rs | 4 +++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index 61398a7d66e6..0d2daabb9e32 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -333,6 +333,7 @@ impl TargetInfo { crate_type: &CrateType, flavor: FileFlavor, target_triple: &str, + split_debuginfo: Option<&str>, ) -> CargoResult>> { let crate_type = if *crate_type == CrateType::Lib { CrateType::Rlib @@ -462,6 +463,14 @@ impl TargetInfo { // preserved. should_replace_hyphens: true, }) + } else if split_debuginfo == Some("packed") { + ret.push(FileType { + suffix: ".dwp".to_string(), + prefix: prefix.clone(), + flavor: FileFlavor::DebugInfo, + crate_type: Some(crate_type), + should_replace_hyphens: false, + }) } } @@ -494,11 +503,19 @@ impl TargetInfo { mode: CompileMode, target_kind: &TargetKind, target_triple: &str, + split_debuginfo: Option<&str>, ) -> CargoResult<(Vec, Vec)> { match mode { - CompileMode::Build => self.calc_rustc_outputs(target_kind, target_triple), + CompileMode::Build => { + self.calc_rustc_outputs(target_kind, target_triple, split_debuginfo) + } CompileMode::Test | CompileMode::Bench => { - match self.file_types(&CrateType::Bin, FileFlavor::Normal, target_triple)? { + match self.file_types( + &CrateType::Bin, + FileFlavor::Normal, + target_triple, + split_debuginfo, + )? { Some(fts) => Ok((fts, Vec::new())), None => Ok((Vec::new(), vec![CrateType::Bin])), } @@ -517,6 +534,7 @@ impl TargetInfo { &self, target_kind: &TargetKind, target_triple: &str, + split_debuginfo: Option<&str>, ) -> CargoResult<(Vec, Vec)> { let mut unsupported = Vec::new(); let mut result = Vec::new(); @@ -527,7 +545,7 @@ impl TargetInfo { } else { FileFlavor::Normal }; - let file_types = self.file_types(crate_type, flavor, target_triple)?; + let file_types = self.file_types(crate_type, flavor, target_triple, split_debuginfo)?; match file_types { Some(types) => { result.extend(types); diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs index dcfaabf327a1..5a3d51bd619f 100644 --- a/src/cargo/core/compiler/context/compilation_files.rs +++ b/src/cargo/core/compiler/context/compilation_files.rs @@ -346,6 +346,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { CompileMode::Build, &TargetKind::Bin, bcx.target_data.short_name(&kind), + None, ) .expect("target must support `bin`"); @@ -486,8 +487,12 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { let info = bcx.target_data.info(unit.kind); let triple = bcx.target_data.short_name(&unit.kind); - let (file_types, unsupported) = - info.rustc_outputs(unit.mode, unit.target.kind(), triple)?; + let (file_types, unsupported) = info.rustc_outputs( + unit.mode, + unit.target.kind(), + triple, + unit.profile.split_debuginfo.as_deref(), + )?; if file_types.is_empty() { if !unsupported.is_empty() { let unsupported_strs: Vec<_> = unsupported.iter().map(|ct| ct.as_str()).collect(); diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 507c2d89b1ce..83a607eee370 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -174,7 +174,7 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> { let (file_types, _unsupported) = target_data .info(*compile_kind) - .rustc_outputs(mode, target.kind(), triple)?; + .rustc_outputs(mode, target.kind(), triple, None)?; let (dir, uplift_dir) = match target.kind() { TargetKind::ExampleBin | TargetKind::ExampleLib(..) => { (layout.examples(), Some(layout.examples())) @@ -203,6 +203,8 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> { rm_rf_glob(&split_debuginfo_obj, config, &mut progress)?; let split_debuginfo_dwo = dir_glob.join(format!("{}.*.dwo", crate_name)); rm_rf_glob(&split_debuginfo_dwo, config, &mut progress)?; + let split_debuginfo_dwp = dir_glob.join(format!("{}.*.dwp", crate_name)); + rm_rf_glob(&split_debuginfo_dwp, config, &mut progress)?; // Remove the uplifted copy. if let Some(uplift_dir) = uplift_dir {