Skip to content

Commit e6c43cf

Browse files
committed
Auto merge of rust-lang#95685 - oxidecomputer:restore-static-dwarf, r=pnkfelix
Revert "Work around invalid DWARF bugs for fat LTO" Since September, the toolchain has not been generating reliable DWARF information for static variables when LTO is on. This has affected projects in the embedded space where the use of LTO is typical. In our case, it has kept us from bumping past the 2021-09-22 nightly toolchain lest our debugger break. This has been a pretty dramatic regression for people using debuggers and static variables. See rust-lang#90357 for more info and a repro case. This commit is a mechanical revert of d5de680 from PR rust-lang#89041, which caused the issue. (Note on that PR that the commit's author has requested it be reverted.) I have locally verified that this fixes rust-lang#90357 by restoring the functionality of both the repro case I posted on that bug, and debugger behavior on real programs. There do not appear to be test cases for this in the toolchain; if I've missed them, point me at 'em and I'll update them.
2 parents 8c1cc82 + 2085d6a commit e6c43cf

File tree

5 files changed

+95
-27
lines changed

5 files changed

+95
-27
lines changed

compiler/rustc_codegen_llvm/src/back/lto.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -325,20 +325,6 @@ fn fat_lto(
325325
drop(linker);
326326
save_temp_bitcode(cgcx, &module, "lto.input");
327327

328-
// Fat LTO also suffers from the invalid DWARF issue similar to Thin LTO.
329-
// Here we rewrite all `DICompileUnit` pointers if there is only one `DICompileUnit`.
330-
// This only works around the problem when codegen-units = 1.
331-
// Refer to the comments in the `optimize_thin_module` function for more details.
332-
let mut cu1 = ptr::null_mut();
333-
let mut cu2 = ptr::null_mut();
334-
unsafe { llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2) };
335-
if !cu2.is_null() {
336-
let _timer =
337-
cgcx.prof.generic_activity_with_arg("LLVM_fat_lto_patch_debuginfo", &*module.name);
338-
unsafe { llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1) };
339-
save_temp_bitcode(cgcx, &module, "fat-lto-after-patch");
340-
}
341-
342328
// Internalize everything below threshold to help strip out more modules and such.
343329
unsafe {
344330
let ptr = symbols_below_threshold.as_ptr();
@@ -769,7 +755,7 @@ pub unsafe fn optimize_thin_module(
769755
// an error.
770756
let mut cu1 = ptr::null_mut();
771757
let mut cu2 = ptr::null_mut();
772-
llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
758+
llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
773759
if !cu2.is_null() {
774760
let msg = "multiple source DICompileUnits found";
775761
return Err(write::llvm_err(&diag_handler, msg));
@@ -858,7 +844,7 @@ pub unsafe fn optimize_thin_module(
858844
let _timer = cgcx
859845
.prof
860846
.generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name());
861-
llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1);
847+
llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1);
862848
save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
863849
}
864850

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -2508,8 +2508,12 @@ extern "C" {
25082508
len: usize,
25092509
out_len: &mut usize,
25102510
) -> *const u8;
2511-
pub fn LLVMRustLTOGetDICompileUnit(M: &Module, CU1: &mut *mut c_void, CU2: &mut *mut c_void);
2512-
pub fn LLVMRustLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
2511+
pub fn LLVMRustThinLTOGetDICompileUnit(
2512+
M: &Module,
2513+
CU1: &mut *mut c_void,
2514+
CU2: &mut *mut c_void,
2515+
);
2516+
pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
25132517

25142518
pub fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>;
25152519
pub fn LLVMRustLinkerAdd(

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1715,7 +1715,7 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data,
17151715
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
17161716
// the comment in `back/lto.rs` for why this exists.
17171717
extern "C" void
1718-
LLVMRustLTOGetDICompileUnit(LLVMModuleRef Mod,
1718+
LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
17191719
DICompileUnit **A,
17201720
DICompileUnit **B) {
17211721
Module *M = unwrap(Mod);
@@ -1733,7 +1733,7 @@ LLVMRustLTOGetDICompileUnit(LLVMModuleRef Mod,
17331733
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
17341734
// the comment in `back/lto.rs` for why this exists.
17351735
extern "C" void
1736-
LLVMRustLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1736+
LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
17371737
Module *M = unwrap(Mod);
17381738

17391739
// If the original source module didn't have a `DICompileUnit` then try to
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Caveat - gdb doesn't know about UTF-32 character encoding and will print a
2+
// rust char as only its numerical value.
3+
4+
// min-lldb-version: 310
5+
// min-gdb-version: 8.0
6+
7+
// no-prefer-dynamic
8+
// compile-flags:-g -C lto
9+
// gdb-command:run
10+
// gdbg-command:print 'basic_types_globals::B'
11+
// gdbr-command:print B
12+
// gdb-check:$1 = false
13+
// gdbg-command:print 'basic_types_globals::I'
14+
// gdbr-command:print I
15+
// gdb-check:$2 = -1
16+
// gdbg-command:print 'basic_types_globals::C'
17+
// gdbr-command:print C
18+
// gdbg-check:$3 = 97
19+
// gdbr-check:$3 = 97
20+
// gdbg-command:print/d 'basic_types_globals::I8'
21+
// gdbr-command:print I8
22+
// gdb-check:$4 = 68
23+
// gdbg-command:print 'basic_types_globals::I16'
24+
// gdbr-command:print I16
25+
// gdb-check:$5 = -16
26+
// gdbg-command:print 'basic_types_globals::I32'
27+
// gdbr-command:print I32
28+
// gdb-check:$6 = -32
29+
// gdbg-command:print 'basic_types_globals::I64'
30+
// gdbr-command:print I64
31+
// gdb-check:$7 = -64
32+
// gdbg-command:print 'basic_types_globals::U'
33+
// gdbr-command:print U
34+
// gdb-check:$8 = 1
35+
// gdbg-command:print/d 'basic_types_globals::U8'
36+
// gdbr-command:print U8
37+
// gdb-check:$9 = 100
38+
// gdbg-command:print 'basic_types_globals::U16'
39+
// gdbr-command:print U16
40+
// gdb-check:$10 = 16
41+
// gdbg-command:print 'basic_types_globals::U32'
42+
// gdbr-command:print U32
43+
// gdb-check:$11 = 32
44+
// gdbg-command:print 'basic_types_globals::U64'
45+
// gdbr-command:print U64
46+
// gdb-check:$12 = 64
47+
// gdbg-command:print 'basic_types_globals::F32'
48+
// gdbr-command:print F32
49+
// gdb-check:$13 = 2.5
50+
// gdbg-command:print 'basic_types_globals::F64'
51+
// gdbr-command:print F64
52+
// gdb-check:$14 = 3.5
53+
// gdb-command:continue
54+
55+
#![allow(unused_variables)]
56+
#![feature(omit_gdb_pretty_printer_section)]
57+
#![omit_gdb_pretty_printer_section]
58+
59+
// N.B. These are `mut` only so they don't constant fold away.
60+
static mut B: bool = false;
61+
static mut I: isize = -1;
62+
static mut C: char = 'a';
63+
static mut I8: i8 = 68;
64+
static mut I16: i16 = -16;
65+
static mut I32: i32 = -32;
66+
static mut I64: i64 = -64;
67+
static mut U: usize = 1;
68+
static mut U8: u8 = 100;
69+
static mut U16: u16 = 16;
70+
static mut U32: u32 = 32;
71+
static mut U64: u64 = 64;
72+
static mut F32: f32 = 2.5;
73+
static mut F64: f64 = 3.5;
74+
75+
fn main() {
76+
_zzz(); // #break
77+
78+
let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64) };
79+
}
80+
81+
fn _zzz() {()}

src/test/debuginfo/basic-types-globals.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
2-
// as its numerical value along with its associated ASCII char, there
3-
// doesn't seem to be any way around this. Also, gdb doesn't know
4-
// about UTF-32 character encoding and will print a rust char as only
5-
// its numerical value.
1+
// Caveat - gdb doesn't know about UTF-32 character encoding and will print a
2+
// rust char as only its numerical value.
63

74
// min-lldb-version: 310
8-
// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155
5+
// min-gdb-version: 8.0
96

107
// compile-flags:-g
118
// gdb-command:run
@@ -18,7 +15,7 @@
1815
// gdbg-command:print 'basic_types_globals::C'
1916
// gdbr-command:print C
2017
// gdbg-check:$3 = 97
21-
// gdbr-check:$3 = 97 'a'
18+
// gdbr-check:$3 = 97
2219
// gdbg-command:print/d 'basic_types_globals::I8'
2320
// gdbr-command:print I8
2421
// gdb-check:$4 = 68

0 commit comments

Comments
 (0)