From b5acbd3f0360b221e9885be4c99957272b0ede82 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 19 May 2017 10:55:25 +0200 Subject: [PATCH] debuginfo: Generate unique DW_AT_names for compilation units to work around OSX linker bug. --- src/librustc_trans/context.rs | 5 +- src/librustc_trans/debuginfo/metadata.rs | 29 +++++----- src/test/debuginfo/multi-cgu.rs | 67 ++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 src/test/debuginfo/multi-cgu.rs diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 90cda2f5cad3d..c2f2c63790a4c 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -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 diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 188f8ee336637..7d8b8161abe02 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -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 { diff --git a/src/test/debuginfo/multi-cgu.rs b/src/test/debuginfo/multi-cgu.rs new file mode 100644 index 0000000000000..f4f9f92396f2c --- /dev/null +++ b/src/test/debuginfo/multi-cgu.rs @@ -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 or the MIT license +// , 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() {}