diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index a3bcce34566cb..da30cb4516d1c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -6,6 +6,7 @@ use std::{assert_matches, iter, ptr}; use libc::{c_longlong, c_uint}; use rustc_abi::{Align, Endian, Layout, NumScalableVectors, Size}; +use rustc_ast::{IntTy, UintTy}; use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo}; use rustc_codegen_ssa::traits::*; use rustc_hir::def::{CtorKind, DefKind}; @@ -795,9 +796,50 @@ fn build_basic_type_di_node<'ll, 'tcx>( _ => bug!("debuginfo::build_basic_type_di_node - `t` is invalid type"), }; - let ty_di_node = create_basic_type(cx, name, cx.size_of(t), encoding); + // Around LLDB 21 or 22, LLDB started using prebuilt Clang type nodes for primitives rather than + // reading the full DWARF data. These nodes are based on the size and signedness of the + // primitive, and ignore pretty much all other fields. This causes 2 issues: + // 1. type names get normalized to C-style names which isn't ideal. The normalization occurs + // even in generic args. + // 2. if you have a generic type `S`, and 2 instantiations are `S` + // and `S` (on a 64-bit target), the use of prebuilt nodes causes a name collision. + // Whichever instantiation is interacted with first will work fine, all others will break a + // bunch of stuff in the LLDB pipeline. To avoid this, we explicitly treat `usize` and `isize` + // as typedefs of their equivalent types. For more info see: llvm/llvm-project#196812 + + let mut needs_typedef = cpp_like_debuginfo; + + let ty_di_node = match t.kind() { + ty::Uint(UintTy::Usize) => { + needs_typedef = true; + + let equivalent = match t.primitive_size(cx.tcx).bits() { + 8 => cx.tcx.types.u8, + 16 => cx.tcx.types.u16, + 32 => cx.tcx.types.u32, + 64 => cx.tcx.types.u64, + 128 => cx.tcx.types.u128, + x => bug!("Unexpected signed int size {x}"), + }; + type_di_node(cx, equivalent) + } + ty::Int(IntTy::Isize) => { + needs_typedef = true; + + let equivalent = match t.primitive_size(cx.tcx).bits() { + 8 => cx.tcx.types.i8, + 16 => cx.tcx.types.i16, + 32 => cx.tcx.types.i32, + 64 => cx.tcx.types.i64, + 128 => cx.tcx.types.i128, + x => bug!("Unexpected signed int size: {x}"), + }; + type_di_node(cx, equivalent) + } + _ => create_basic_type(cx, name, cx.size_of(t), encoding), + }; - if !cpp_like_debuginfo { + if !needs_typedef { return DINodeCreationResult::new(ty_di_node, false); } diff --git a/tests/debuginfo/basic-types/lldb_input/non_windows.json b/tests/debuginfo/basic-types/lldb_input/non_windows.json index af225246e6109..67c45674981a2 100644 --- a/tests/debuginfo/basic-types/lldb_input/non_windows.json +++ b/tests/debuginfo/basic-types/lldb_input/non_windows.json @@ -12,7 +12,7 @@ "value": false }, "i": { - "type": "long", + "type": "isize", "pretty_print": "-1", "value": -1 }, @@ -43,7 +43,7 @@ "value": -64 }, "u": { - "type": "unsigned long", + "type": "usize", "pretty_print": "1", "value": 1 }, diff --git a/tests/debuginfo/basic-types/lldb_input/windows_gnu.json b/tests/debuginfo/basic-types/lldb_input/windows_gnu.json index 80c35ffcbea60..06b21d7cb0b35 100644 --- a/tests/debuginfo/basic-types/lldb_input/windows_gnu.json +++ b/tests/debuginfo/basic-types/lldb_input/windows_gnu.json @@ -1,7 +1,7 @@ { "bless_metadata": { "python_version": "3.11.9 (tags/v3.11.9:de54cf5, Apr 2 2024, 10:12:12) [MSC v.1938 64 bit (AMD64)]", - "debugger_version": "lldb version 22.1.2 (https://github.com/llvm/llvm-project revision 1ab49a973e210e97d61e5db6557180dcb92c3e98)\n clang revision 1ab49a973e210e97d61e5db6557180dcb92c3e98\n llvm revision 1ab49a973e210e97d61e5db6557180dcb92c3e98", + "debugger_version": "lldb version 22.1.8 (https://github.com/llvm/llvm-project revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)\n clang revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1\n llvm revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1", "feature_flags": "LLDBFeature.StaticFields|TypeRecognizers|Float128" }, "breakpoints": [ @@ -12,7 +12,7 @@ "value": false }, "i": { - "type": "long long", + "type": "isize", "pretty_print": "-1", "value": -1 }, @@ -43,7 +43,7 @@ "value": -64 }, "u": { - "type": "unsigned long long", + "type": "usize", "pretty_print": "1", "value": 1 }, diff --git a/tests/debuginfo/pretty-std/lldb_input/non_windows.json b/tests/debuginfo/pretty-std/lldb_input/non_windows.json index 04106aed96d7f..82213d82992f2 100644 --- a/tests/debuginfo/pretty-std/lldb_input/non_windows.json +++ b/tests/debuginfo/pretty-std/lldb_input/non_windows.json @@ -162,7 +162,7 @@ }, { "name": "length", - "type": "unsigned long", + "type": "usize", "offset": 8 } ] @@ -171,9 +171,9 @@ "size": 8, "type_class": 4096 }, - "unsigned long": { + "usize": { "size": 8, - "type_class": 4, + "type_class": 32768, "basic_type": 16 }, "int": { @@ -192,7 +192,7 @@ }, { "name": "len", - "type": "unsigned long", + "type": "usize", "offset": 16 } ], @@ -281,7 +281,7 @@ "fields": [ { "name": "__0", - "type": "unsigned long", + "type": "usize", "offset": 0 } ] @@ -297,6 +297,11 @@ "unsigned long" ] }, + "unsigned long": { + "size": 8, + "type_class": 4, + "basic_type": 16 + }, "&str": { "size": 16, "type_class": 16384, @@ -308,7 +313,7 @@ }, { "name": "length", - "type": "unsigned long", + "type": "usize", "offset": 8 } ] @@ -335,7 +340,7 @@ }, { "name": "len", - "type": "unsigned long", + "type": "usize", "offset": 16 } ], diff --git a/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json b/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json index c0f831e31bfe0..9c0eba8559cfe 100644 --- a/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json +++ b/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json @@ -1,7 +1,7 @@ { "bless_metadata": { "python_version": "3.11.9 (tags/v3.11.9:de54cf5, Apr 2 2024, 10:12:12) [MSC v.1938 64 bit (AMD64)]", - "debugger_version": "lldb version 22.1.2 (https://github.com/llvm/llvm-project revision 1ab49a973e210e97d61e5db6557180dcb92c3e98)\n clang revision 1ab49a973e210e97d61e5db6557180dcb92c3e98\n llvm revision 1ab49a973e210e97d61e5db6557180dcb92c3e98", + "debugger_version": "lldb version 22.1.8 (https://github.com/llvm/llvm-project revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)\n clang revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1\n llvm revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1", "feature_flags": "LLDBFeature.StaticFields|TypeRecognizers|Float128" }, "breakpoints": [ @@ -173,7 +173,7 @@ }, { "name": "length", - "type": "unsigned long long", + "type": "usize", "offset": 8 } ] @@ -182,9 +182,9 @@ "size": 8, "type_class": 4096 }, - "unsigned long long": { + "usize": { "size": 8, - "type_class": 4, + "type_class": 32768, "basic_type": 18 }, "int": { @@ -203,7 +203,7 @@ }, { "name": "len", - "type": "unsigned long long", + "type": "usize", "offset": 16 } ], @@ -292,7 +292,7 @@ "fields": [ { "name": "__0", - "type": "unsigned long long", + "type": "usize", "offset": 0 } ] @@ -308,6 +308,11 @@ "unsigned long long" ] }, + "unsigned long long": { + "size": 8, + "type_class": 4, + "basic_type": 18 + }, "&str": { "size": 16, "type_class": 16384, @@ -319,7 +324,7 @@ }, { "name": "length", - "type": "unsigned long long", + "type": "usize", "offset": 8 } ] @@ -346,7 +351,7 @@ }, { "name": "len", - "type": "unsigned long long", + "type": "usize", "offset": 16 } ], diff --git a/tests/debuginfo/rc_arc.rs b/tests/debuginfo/rc_arc.rs index adeb96dba1b80..e1af1eba02193 100644 --- a/tests/debuginfo/rc_arc.rs +++ b/tests/debuginfo/rc_arc.rs @@ -21,6 +21,11 @@ //@ lldb-check:[...] strong=11, weak=2 { value = 111 } //@ lldb-command:v arc //@ lldb-check:[...] strong=21, weak=2 { data = 222 } +//@ lldb-command:continue +//@ lldb-command:v rc_u64 +//@ lldb-check:[...] rc_u64 = strong=1, weak=1 { value = 10 } +//@ lldb-command:v rc_usize +//@ lldb-check:[...] rc_usize = strong=1, weak=1 { value = 20 } // === CDB TESTS ================================================================================== @@ -132,6 +137,11 @@ fn main() { let slice_arc_weak = Arc::downgrade(&slice_arc); zzz(); // #break + + let rc_u64 = Rc::new(10u64); + let rc_usize = Rc::new(20usize); + + zzz(); // #break } fn inc_ref_count(rc: &T, count: usize) {