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
This commit is contained in:
Mark Simulacrum 2017-05-19 14:16:26 -06:00 committed by GitHub
commit 040cd6d15d
3 changed files with 87 additions and 14 deletions

View File

@ -375,7 +375,10 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
let dctx = debuginfo::CrateDebugContext::new(llmod);
debuginfo::metadata::compile_unit_metadata(shared, &dctx, shared.tcx.sess);
debuginfo::metadata::compile_unit_metadata(shared,
codegen_unit.name(),
&dctx,
shared.tcx.sess);
Some(dctx)
} else {
None

View File

@ -762,23 +762,30 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
pub fn compile_unit_metadata(scc: &SharedCrateContext,
codegen_unit_name: &str,
debug_context: &CrateDebugContext,
sess: &Session)
-> DIDescriptor {
let compile_unit_name = match sess.local_crate_source_file {
None => fallback_path(scc),
Some(ref path) => {
CString::new(&path[..]).unwrap()
}
let mut name_in_debuginfo = match sess.local_crate_source_file {
Some(ref path) => path.clone(),
None => scc.tcx().crate_name(LOCAL_CRATE).to_string(),
};
debug!("compile_unit_metadata: {:?}", compile_unit_name);
// The OSX linker has an idiosyncrasy where it will ignore some debuginfo
// if multiple object files with the same DW_AT_name are linked together.
// As a workaround we generate unique names for each object file. Those do
// not correspond to an actual source file but that should be harmless.
if scc.sess().target.target.options.is_like_osx {
name_in_debuginfo.push_str("@");
name_in_debuginfo.push_str(codegen_unit_name);
}
debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
let producer = format!("clang LLVM (rustc version {})",
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
let compile_unit_name = compile_unit_name.as_ptr();
let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap();
let work_dir = CString::new(&sess.working_dir.0[..]).unwrap();
let producer = CString::new(producer).unwrap();
let flags = "\0";
@ -786,7 +793,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
unsafe {
let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
debug_context.builder, compile_unit_name, work_dir.as_ptr());
debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
return llvm::LLVMRustDIBuilderCreateCompileUnit(
debug_context.builder,
@ -798,10 +805,6 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
0,
split_name.as_ptr() as *const _)
};
fn fallback_path(scc: &SharedCrateContext) -> CString {
CString::new(scc.tcx().crate_name(LOCAL_CRATE).to_string()).unwrap()
}
}
struct MetadataCreationResult {

View File

@ -0,0 +1,67 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// This test case makes sure that we get proper break points for binaries
// compiled with multiple codegen units. (see #39160)
// min-lldb-version: 310
// compile-flags:-g -Ccodegen-units=2
// === GDB TESTS ===============================================================
// gdb-command:run
// gdb-command:print xxx
// gdb-check:$1 = 12345
// gdb-command:continue
// gdb-command:print yyy
// gdb-check:$2 = 67890
// gdb-command:continue
// === LLDB TESTS ==============================================================
// lldb-command:run
// lldb-command:print xxx
// lldb-check:[...]$0 = 12345
// lldb-command:continue
// lldb-command:print yyy
// lldb-check:[...]$1 = 67890
// lldb-command:continue
#![feature(omit_gdb_pretty_printer_section)]
#![omit_gdb_pretty_printer_section]
mod a {
pub fn foo(xxx: u32) {
super::_zzz(); // #break
}
}
mod b {
pub fn bar(yyy: u64) {
super::_zzz(); // #break
}
}
fn main() {
a::foo(12345);
b::bar(67890);
}
#[inline(never)]
fn _zzz() {}