Auto merge of #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 #90357 for more info
and a repro case.
This commit is a mechanical revert of
d5de680e20
from PR #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 #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.
This commit is contained in:
commit
e6c43cf8b9
5 changed files with 95 additions and 27 deletions
|
@ -325,20 +325,6 @@ fn fat_lto(
|
||||||
drop(linker);
|
drop(linker);
|
||||||
save_temp_bitcode(cgcx, &module, "lto.input");
|
save_temp_bitcode(cgcx, &module, "lto.input");
|
||||||
|
|
||||||
// Fat LTO also suffers from the invalid DWARF issue similar to Thin LTO.
|
|
||||||
// Here we rewrite all `DICompileUnit` pointers if there is only one `DICompileUnit`.
|
|
||||||
// This only works around the problem when codegen-units = 1.
|
|
||||||
// Refer to the comments in the `optimize_thin_module` function for more details.
|
|
||||||
let mut cu1 = ptr::null_mut();
|
|
||||||
let mut cu2 = ptr::null_mut();
|
|
||||||
unsafe { llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2) };
|
|
||||||
if !cu2.is_null() {
|
|
||||||
let _timer =
|
|
||||||
cgcx.prof.generic_activity_with_arg("LLVM_fat_lto_patch_debuginfo", &*module.name);
|
|
||||||
unsafe { llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1) };
|
|
||||||
save_temp_bitcode(cgcx, &module, "fat-lto-after-patch");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internalize everything below threshold to help strip out more modules and such.
|
// Internalize everything below threshold to help strip out more modules and such.
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = symbols_below_threshold.as_ptr();
|
let ptr = symbols_below_threshold.as_ptr();
|
||||||
|
@ -769,7 +755,7 @@ pub unsafe fn optimize_thin_module(
|
||||||
// an error.
|
// an error.
|
||||||
let mut cu1 = ptr::null_mut();
|
let mut cu1 = ptr::null_mut();
|
||||||
let mut cu2 = ptr::null_mut();
|
let mut cu2 = ptr::null_mut();
|
||||||
llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
|
llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
|
||||||
if !cu2.is_null() {
|
if !cu2.is_null() {
|
||||||
let msg = "multiple source DICompileUnits found";
|
let msg = "multiple source DICompileUnits found";
|
||||||
return Err(write::llvm_err(&diag_handler, msg));
|
return Err(write::llvm_err(&diag_handler, msg));
|
||||||
|
@ -858,7 +844,7 @@ pub unsafe fn optimize_thin_module(
|
||||||
let _timer = cgcx
|
let _timer = cgcx
|
||||||
.prof
|
.prof
|
||||||
.generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name());
|
.generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name());
|
||||||
llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1);
|
llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1);
|
||||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
|
save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2508,8 +2508,12 @@ extern "C" {
|
||||||
len: usize,
|
len: usize,
|
||||||
out_len: &mut usize,
|
out_len: &mut usize,
|
||||||
) -> *const u8;
|
) -> *const u8;
|
||||||
pub fn LLVMRustLTOGetDICompileUnit(M: &Module, CU1: &mut *mut c_void, CU2: &mut *mut c_void);
|
pub fn LLVMRustThinLTOGetDICompileUnit(
|
||||||
pub fn LLVMRustLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
|
M: &Module,
|
||||||
|
CU1: &mut *mut c_void,
|
||||||
|
CU2: &mut *mut c_void,
|
||||||
|
);
|
||||||
|
pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
|
||||||
|
|
||||||
pub fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>;
|
pub fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>;
|
||||||
pub fn LLVMRustLinkerAdd(
|
pub fn LLVMRustLinkerAdd(
|
||||||
|
|
|
@ -1715,7 +1715,7 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data,
|
||||||
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
|
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
|
||||||
// the comment in `back/lto.rs` for why this exists.
|
// the comment in `back/lto.rs` for why this exists.
|
||||||
extern "C" void
|
extern "C" void
|
||||||
LLVMRustLTOGetDICompileUnit(LLVMModuleRef Mod,
|
LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
|
||||||
DICompileUnit **A,
|
DICompileUnit **A,
|
||||||
DICompileUnit **B) {
|
DICompileUnit **B) {
|
||||||
Module *M = unwrap(Mod);
|
Module *M = unwrap(Mod);
|
||||||
|
@ -1733,7 +1733,7 @@ LLVMRustLTOGetDICompileUnit(LLVMModuleRef Mod,
|
||||||
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
|
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
|
||||||
// the comment in `back/lto.rs` for why this exists.
|
// the comment in `back/lto.rs` for why this exists.
|
||||||
extern "C" void
|
extern "C" void
|
||||||
LLVMRustLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
|
LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
|
||||||
Module *M = unwrap(Mod);
|
Module *M = unwrap(Mod);
|
||||||
|
|
||||||
// If the original source module didn't have a `DICompileUnit` then try to
|
// If the original source module didn't have a `DICompileUnit` then try to
|
||||||
|
|
81
src/test/debuginfo/basic-types-globals-lto.rs
Normal file
81
src/test/debuginfo/basic-types-globals-lto.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// Caveat - gdb doesn't know about UTF-32 character encoding and will print a
|
||||||
|
// rust char as only its numerical value.
|
||||||
|
|
||||||
|
// min-lldb-version: 310
|
||||||
|
// min-gdb-version: 8.0
|
||||||
|
|
||||||
|
// no-prefer-dynamic
|
||||||
|
// compile-flags:-g -C lto
|
||||||
|
// gdb-command:run
|
||||||
|
// gdbg-command:print 'basic_types_globals::B'
|
||||||
|
// gdbr-command:print B
|
||||||
|
// gdb-check:$1 = false
|
||||||
|
// gdbg-command:print 'basic_types_globals::I'
|
||||||
|
// gdbr-command:print I
|
||||||
|
// gdb-check:$2 = -1
|
||||||
|
// gdbg-command:print 'basic_types_globals::C'
|
||||||
|
// gdbr-command:print C
|
||||||
|
// gdbg-check:$3 = 97
|
||||||
|
// gdbr-check:$3 = 97
|
||||||
|
// gdbg-command:print/d 'basic_types_globals::I8'
|
||||||
|
// gdbr-command:print I8
|
||||||
|
// gdb-check:$4 = 68
|
||||||
|
// gdbg-command:print 'basic_types_globals::I16'
|
||||||
|
// gdbr-command:print I16
|
||||||
|
// gdb-check:$5 = -16
|
||||||
|
// gdbg-command:print 'basic_types_globals::I32'
|
||||||
|
// gdbr-command:print I32
|
||||||
|
// gdb-check:$6 = -32
|
||||||
|
// gdbg-command:print 'basic_types_globals::I64'
|
||||||
|
// gdbr-command:print I64
|
||||||
|
// gdb-check:$7 = -64
|
||||||
|
// gdbg-command:print 'basic_types_globals::U'
|
||||||
|
// gdbr-command:print U
|
||||||
|
// gdb-check:$8 = 1
|
||||||
|
// gdbg-command:print/d 'basic_types_globals::U8'
|
||||||
|
// gdbr-command:print U8
|
||||||
|
// gdb-check:$9 = 100
|
||||||
|
// gdbg-command:print 'basic_types_globals::U16'
|
||||||
|
// gdbr-command:print U16
|
||||||
|
// gdb-check:$10 = 16
|
||||||
|
// gdbg-command:print 'basic_types_globals::U32'
|
||||||
|
// gdbr-command:print U32
|
||||||
|
// gdb-check:$11 = 32
|
||||||
|
// gdbg-command:print 'basic_types_globals::U64'
|
||||||
|
// gdbr-command:print U64
|
||||||
|
// gdb-check:$12 = 64
|
||||||
|
// gdbg-command:print 'basic_types_globals::F32'
|
||||||
|
// gdbr-command:print F32
|
||||||
|
// gdb-check:$13 = 2.5
|
||||||
|
// gdbg-command:print 'basic_types_globals::F64'
|
||||||
|
// gdbr-command:print F64
|
||||||
|
// gdb-check:$14 = 3.5
|
||||||
|
// gdb-command:continue
|
||||||
|
|
||||||
|
#![allow(unused_variables)]
|
||||||
|
#![feature(omit_gdb_pretty_printer_section)]
|
||||||
|
#![omit_gdb_pretty_printer_section]
|
||||||
|
|
||||||
|
// N.B. These are `mut` only so they don't constant fold away.
|
||||||
|
static mut B: bool = false;
|
||||||
|
static mut I: isize = -1;
|
||||||
|
static mut C: char = 'a';
|
||||||
|
static mut I8: i8 = 68;
|
||||||
|
static mut I16: i16 = -16;
|
||||||
|
static mut I32: i32 = -32;
|
||||||
|
static mut I64: i64 = -64;
|
||||||
|
static mut U: usize = 1;
|
||||||
|
static mut U8: u8 = 100;
|
||||||
|
static mut U16: u16 = 16;
|
||||||
|
static mut U32: u32 = 32;
|
||||||
|
static mut U64: u64 = 64;
|
||||||
|
static mut F32: f32 = 2.5;
|
||||||
|
static mut F64: f64 = 3.5;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_zzz(); // #break
|
||||||
|
|
||||||
|
let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64) };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _zzz() {()}
|
|
@ -1,11 +1,8 @@
|
||||||
// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
|
// Caveat - gdb doesn't know about UTF-32 character encoding and will print a
|
||||||
// as its numerical value along with its associated ASCII char, there
|
// rust char as only its numerical value.
|
||||||
// doesn't seem to be any way around this. Also, gdb doesn't know
|
|
||||||
// about UTF-32 character encoding and will print a rust char as only
|
|
||||||
// its numerical value.
|
|
||||||
|
|
||||||
// min-lldb-version: 310
|
// min-lldb-version: 310
|
||||||
// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155
|
// min-gdb-version: 8.0
|
||||||
|
|
||||||
// compile-flags:-g
|
// compile-flags:-g
|
||||||
// gdb-command:run
|
// gdb-command:run
|
||||||
|
@ -18,7 +15,7 @@
|
||||||
// gdbg-command:print 'basic_types_globals::C'
|
// gdbg-command:print 'basic_types_globals::C'
|
||||||
// gdbr-command:print C
|
// gdbr-command:print C
|
||||||
// gdbg-check:$3 = 97
|
// gdbg-check:$3 = 97
|
||||||
// gdbr-check:$3 = 97 'a'
|
// gdbr-check:$3 = 97
|
||||||
// gdbg-command:print/d 'basic_types_globals::I8'
|
// gdbg-command:print/d 'basic_types_globals::I8'
|
||||||
// gdbr-command:print I8
|
// gdbr-command:print I8
|
||||||
// gdb-check:$4 = 68
|
// gdb-check:$4 = 68
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue