From cc3786db90dd3fa47b2eb396427b13ad869e767b Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sun, 6 Sep 2026 03:09:37 -0500 Subject: [PATCH] force u8/i8 numeric formatting for lldb --- src/etc/lldb_lookup.py | 32 +++++++++++++++++++ src/etc/lldb_providers.py | 26 ++++++++++++++- .../basic-types/lldb_input/non_windows.json | 24 +++++++++++--- .../basic-types/lldb_input/windows_gnu.json | 24 +++++++++++--- .../basic-types/lldb_input/windows_msvc.json | 24 +++++++++++--- tests/debuginfo/borrowed-basic.rs | 6 ++-- tests/debuginfo/reference-debuginfo.rs | 6 ++-- tests/debuginfo/strings-and-strs.rs | 11 +++++-- tests/debuginfo/union-smoke.rs | 4 +-- 9 files changed, 133 insertions(+), 24 deletions(-) diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index f45506e0c53a7..ed43b434e2de8 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -126,6 +126,38 @@ def register_providers_compatibility(): global RUST_CATEGORY + # Don't format 8-bit builtins as chars + unsigned_format = lldb.SBTypeFormat( + lldb.eFormatUnsigned, + lldb.eTypeOptionCascade + | lldb.eTypeOptionSkipPointers + | lldb.eTypeOptionSkipReferences, + ) + + RUST_CATEGORY.AddTypeFormat(lldb.SBTypeNameSpecifier("u8", False), unsigned_format) + RUST_CATEGORY.AddTypeFormat( + lldb.SBTypeNameSpecifier("unsigned char", False), + unsigned_format, + ) + + signed_format = lldb.SBTypeFormat( + lldb.eFormatDecimal, + lldb.eTypeOptionCascade + | lldb.eTypeOptionSkipPointers + | lldb.eTypeOptionSkipReferences, + ) + RUST_CATEGORY.AddTypeFormat( + lldb.SBTypeNameSpecifier("i8", False), lldb.SBTypeFormat(lldb.eFormatDecimal) + ) + + # i8 translates to signed char on msvc + RUST_CATEGORY.AddTypeFormat( + lldb.SBTypeNameSpecifier("signed char", False), + signed_format, + ) + # Does not conflict with rust char, which ends up with the type name `char32_t` + RUST_CATEGORY.AddTypeFormat(lldb.SBTypeNameSpecifier("char", False), signed_format) + if LLDBFeature.TypeRecognizers in FEATURE_FLAGS: # enforce uniform aggregate formatting register_summary( diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 4fdc9e28363b6..16025d9b66c96 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -680,6 +680,9 @@ def get_child_at_index(self, index: int) -> Optional[SBValue]: element = self.data_ptr.CreateValueFromAddress( f"[{index}]", address, self.data_ptr.GetType().GetPointeeType() ) + + element.SetFormat(eFormatChar) + return element def get_type_name(self): @@ -1154,10 +1157,28 @@ def has_children(self) -> bool: class StdSliceSyntheticProvider: - __slots__ = ["valobj", "length", "data_ptr", "element_type", "element_size"] + __slots__ = [ + "valobj", + "length", + "data_ptr", + "element_type", + "element_size", + "is_str", + ] def __init__(self, valobj: SBValue, _dict: LLDBOpaque): self.valobj = valobj + type_name = self.valobj.GetTypeName() + self.is_str = type_name.startswith("alloc::boxed::Box", + "ref_mut$", + "ptr_const$", + "ptr_mut$", + } self.update() def num_children(self) -> int: @@ -1176,6 +1197,9 @@ def get_child_at_index(self, index: int) -> Optional[SBValue]: element = self.data_ptr.CreateValueFromAddress( "[%s]" % index, address, self.element_type ) + + if self.is_str: + element.SetFormat(eFormatChar) return element def update(self): diff --git a/tests/debuginfo/basic-types/lldb_input/non_windows.json b/tests/debuginfo/basic-types/lldb_input/non_windows.json index e1cfbe77d0c5c..af225246e6109 100644 --- a/tests/debuginfo/basic-types/lldb_input/non_windows.json +++ b/tests/debuginfo/basic-types/lldb_input/non_windows.json @@ -23,8 +23,9 @@ }, "i8": { "type": "char", - "pretty_print": "'D'", - "value": 68 + "pretty_print": "68", + "value": 68, + "format": 9 }, "i16": { "type": "short", @@ -48,8 +49,9 @@ }, "u8": { "type": "unsigned char", - "pretty_print": "'d'", - "value": 100 + "pretty_print": "100", + "value": 100, + "format": 18 }, "u16": { "type": "unsigned short", @@ -77,5 +79,17 @@ "value": 3.5 } } - ] + ], + "types": { + "char": { + "size": 1, + "type_class": 4, + "basic_type": 3 + }, + "unsigned char": { + "size": 1, + "type_class": 4, + "basic_type": 4 + } + } } diff --git a/tests/debuginfo/basic-types/lldb_input/windows_gnu.json b/tests/debuginfo/basic-types/lldb_input/windows_gnu.json index bcbcaa6ddf4e4..80c35ffcbea60 100644 --- a/tests/debuginfo/basic-types/lldb_input/windows_gnu.json +++ b/tests/debuginfo/basic-types/lldb_input/windows_gnu.json @@ -23,8 +23,9 @@ }, "i8": { "type": "char", - "pretty_print": "'D'", - "value": 68 + "pretty_print": "68", + "value": 68, + "format": 9 }, "i16": { "type": "short", @@ -48,8 +49,9 @@ }, "u8": { "type": "unsigned char", - "pretty_print": "'d'", - "value": 100 + "pretty_print": "100", + "value": 100, + "format": 18 }, "u16": { "type": "unsigned short", @@ -77,5 +79,17 @@ "value": 3.5 } } - ] + ], + "types": { + "char": { + "size": 1, + "type_class": 4, + "basic_type": 3 + }, + "unsigned char": { + "size": 1, + "type_class": 4, + "basic_type": 4 + } + } } diff --git a/tests/debuginfo/basic-types/lldb_input/windows_msvc.json b/tests/debuginfo/basic-types/lldb_input/windows_msvc.json index 047d6d6e08768..0a7b134b4f683 100644 --- a/tests/debuginfo/basic-types/lldb_input/windows_msvc.json +++ b/tests/debuginfo/basic-types/lldb_input/windows_msvc.json @@ -23,8 +23,9 @@ }, "i8": { "type": "signed char", - "pretty_print": "'D'", - "value": 68 + "pretty_print": "68", + "value": 68, + "format": 9 }, "i16": { "type": "short", @@ -48,8 +49,9 @@ }, "u8": { "type": "unsigned char", - "pretty_print": "'d'", - "value": 100 + "pretty_print": "100", + "value": 100, + "format": 18 }, "u16": { "type": "unsigned short", @@ -77,5 +79,17 @@ "value": 3.5 } } - ] + ], + "types": { + "signed char": { + "size": 1, + "type_class": 4, + "basic_type": 3 + }, + "unsigned char": { + "size": 1, + "type_class": 4, + "basic_type": 4 + } + } } diff --git a/tests/debuginfo/borrowed-basic.rs b/tests/debuginfo/borrowed-basic.rs index a3cffe3c65202..28dd86a796cec 100644 --- a/tests/debuginfo/borrowed-basic.rs +++ b/tests/debuginfo/borrowed-basic.rs @@ -60,9 +60,11 @@ //@ lldb-command:v *int_ref //@ lldb-check:[...] -1 +//@ lldb-command:v *char_ref +//@ lldb-check: [...] U+0x00000061 U'a' //@ lldb-command:v *i8_ref -//@ lldb-check:[...] 'D' +//@ lldb-check:[...] 68 //@ lldb-command:v *i16_ref //@ lldb-check:[...] -16 @@ -77,7 +79,7 @@ //@ lldb-check:[...] 1 //@ lldb-command:v *u8_ref -//@ lldb-check:[...] 'd' +//@ lldb-check:[...] 100 //@ lldb-command:v *u16_ref //@ lldb-check:[...] 16 diff --git a/tests/debuginfo/reference-debuginfo.rs b/tests/debuginfo/reference-debuginfo.rs index 14e5d798195ba..11a8fcc8f1e9d 100644 --- a/tests/debuginfo/reference-debuginfo.rs +++ b/tests/debuginfo/reference-debuginfo.rs @@ -67,9 +67,11 @@ //@ lldb-command:v *int_ref //@ lldb-check:[...] -1 +//@ lldb-command:v *char_ref +//@ lldb-check: [...] U+0x00000061 U'a' //@ lldb-command:v *i8_ref -//@ lldb-check:[...] 'D' +//@ lldb-check:[...] 68 //@ lldb-command:v *i16_ref //@ lldb-check:[...] -16 @@ -84,7 +86,7 @@ //@ lldb-check:[...] 1 //@ lldb-command:v *u8_ref -//@ lldb-check:[...] 'd' +//@ lldb-check:[...] 100 //@ lldb-command:v *u16_ref //@ lldb-check:[...] 16 diff --git a/tests/debuginfo/strings-and-strs.rs b/tests/debuginfo/strings-and-strs.rs index a860aa6106d07..0a7f4b13c4e56 100644 --- a/tests/debuginfo/strings-and-strs.rs +++ b/tests/debuginfo/strings-and-strs.rs @@ -48,8 +48,15 @@ //@ lldb-command:v box_str //@ lldb-check:(alloc::boxed::Box) box_str = "World" { [0] = 'W' [1] = 'o' [2] = 'r' [3] = 'l' [4] = 'd' } -//@ lldb-command:v rc_str -//@ lldb-check:(alloc::rc::Rc) rc_str = strong=1, weak=0 { value = "World" } +// Disabled temporarily since it only "works" by accident +// `value` is a wide pointer, whose `data_ptr` type, according to LLDB, is `unsigned char[]`. LLDB +// reads this as a c-string by default. On Linux this fairly consistenly results in the expected +// output below. On Windows, the string data is often not followed by a null byte and attempts to +// read OOB memory. This will be fixed as part of #161657 +// lldb-command:v rc_str + +// ignore-tidy-linelength +// lldb-check:(alloc::rc::Rc) rc_str = strong=1, weak=0 { value = "World" } #![allow(unused_variables)] diff --git a/tests/debuginfo/union-smoke.rs b/tests/debuginfo/union-smoke.rs index bced679086144..c4c31704f4e71 100644 --- a/tests/debuginfo/union-smoke.rs +++ b/tests/debuginfo/union-smoke.rs @@ -14,10 +14,10 @@ //@ lldb-command:run //@ lldb-command:v u -//@ lldb-check:[...] {a:('\x02', '\x02'), b:514} +//@ lldb-check:[...] {a:(2, 2), b:514} //@ lldb-command:print union_smoke::SU -//@ lldb-check:[...] {a:('\x01', '\x01'), b:257} +//@ lldb-check:[...] {a:(1, 1), b:257} #![allow(unused)]