Skip to content

Commit 040cd6d

Browse files
Rollup merge of #42100 - michaelwoerister:fix-osx-multi-cgu-debuginfo, r=jdm
debuginfo: Generate unique DW_AT_names for compilation units to work around OSX linker bug This should fix issue #39160 and does not seem to cause any problems. cc @tromey, @Manishearth r? @jdm
2 parents 5ded76c + b5acbd3 commit 040cd6d

File tree

3 files changed

+87
-14
lines changed

3 files changed

+87
-14
lines changed

src/librustc_trans/context.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,10 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
375375

376376
let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
377377
let dctx = debuginfo::CrateDebugContext::new(llmod);
378-
debuginfo::metadata::compile_unit_metadata(shared, &dctx, shared.tcx.sess);
378+
debuginfo::metadata::compile_unit_metadata(shared,
379+
codegen_unit.name(),
380+
&dctx,
381+
shared.tcx.sess);
379382
Some(dctx)
380383
} else {
381384
None

src/librustc_trans/debuginfo/metadata.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -762,31 +762,38 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
762762
}
763763

764764
pub fn compile_unit_metadata(scc: &SharedCrateContext,
765+
codegen_unit_name: &str,
765766
debug_context: &CrateDebugContext,
766767
sess: &Session)
767768
-> DIDescriptor {
768-
let compile_unit_name = match sess.local_crate_source_file {
769-
None => fallback_path(scc),
770-
Some(ref path) => {
771-
CString::new(&path[..]).unwrap()
772-
}
769+
let mut name_in_debuginfo = match sess.local_crate_source_file {
770+
Some(ref path) => path.clone(),
771+
None => scc.tcx().crate_name(LOCAL_CRATE).to_string(),
773772
};
774773

775-
debug!("compile_unit_metadata: {:?}", compile_unit_name);
774+
// The OSX linker has an idiosyncrasy where it will ignore some debuginfo
775+
// if multiple object files with the same DW_AT_name are linked together.
776+
// As a workaround we generate unique names for each object file. Those do
777+
// not correspond to an actual source file but that should be harmless.
778+
if scc.sess().target.target.options.is_like_osx {
779+
name_in_debuginfo.push_str("@");
780+
name_in_debuginfo.push_str(codegen_unit_name);
781+
}
782+
783+
debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
776784
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
777785
let producer = format!("clang LLVM (rustc version {})",
778786
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
779787

780-
let compile_unit_name = compile_unit_name.as_ptr();
781-
788+
let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap();
782789
let work_dir = CString::new(&sess.working_dir.0[..]).unwrap();
783790
let producer = CString::new(producer).unwrap();
784791
let flags = "\0";
785792
let split_name = "\0";
786793

787794
unsafe {
788795
let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
789-
debug_context.builder, compile_unit_name, work_dir.as_ptr());
796+
debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
790797

791798
return llvm::LLVMRustDIBuilderCreateCompileUnit(
792799
debug_context.builder,
@@ -798,10 +805,6 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
798805
0,
799806
split_name.as_ptr() as *const _)
800807
};
801-
802-
fn fallback_path(scc: &SharedCrateContext) -> CString {
803-
CString::new(scc.tcx().crate_name(LOCAL_CRATE).to_string()).unwrap()
804-
}
805808
}
806809

807810
struct MetadataCreationResult {

src/test/debuginfo/multi-cgu.rs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
// This test case makes sure that we get proper break points for binaries
13+
// compiled with multiple codegen units. (see #39160)
14+
15+
16+
// min-lldb-version: 310
17+
18+
// compile-flags:-g -Ccodegen-units=2
19+
20+
// === GDB TESTS ===============================================================
21+
22+
// gdb-command:run
23+
24+
// gdb-command:print xxx
25+
// gdb-check:$1 = 12345
26+
// gdb-command:continue
27+
28+
// gdb-command:print yyy
29+
// gdb-check:$2 = 67890
30+
// gdb-command:continue
31+
32+
33+
// === LLDB TESTS ==============================================================
34+
35+
// lldb-command:run
36+
37+
// lldb-command:print xxx
38+
// lldb-check:[...]$0 = 12345
39+
// lldb-command:continue
40+
41+
// lldb-command:print yyy
42+
// lldb-check:[...]$1 = 67890
43+
// lldb-command:continue
44+
45+
46+
#![feature(omit_gdb_pretty_printer_section)]
47+
#![omit_gdb_pretty_printer_section]
48+
49+
mod a {
50+
pub fn foo(xxx: u32) {
51+
super::_zzz(); // #break
52+
}
53+
}
54+
55+
mod b {
56+
pub fn bar(yyy: u64) {
57+
super::_zzz(); // #break
58+
}
59+
}
60+
61+
fn main() {
62+
a::foo(12345);
63+
b::bar(67890);
64+
}
65+
66+
#[inline(never)]
67+
fn _zzz() {}

0 commit comments

Comments
 (0)