Skip to content

Commit 4f59533

Browse files
committed
add alternate inner type lookup for vec/string for missing template args
1 parent 2b8ff75 commit 4f59533

File tree

2 files changed

+86
-7
lines changed

2 files changed

+86
-7
lines changed

src/etc/lldb_commands

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Forces test-compliant formatting to all other types
22
type summary add -F _ -e -x -h "^.*$" --category Rust
33
# Std String
4-
type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)String$" --category Rust
5-
type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust
4+
type synthetic add -l lldb_lookup.StdStringSyntheticProvider -x "^(alloc::([a-z_]+::)+)String$" --category Rust
5+
type summary add -F lldb_lookup.StdStringSummaryProvider -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust
66
# Std str
77
type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?str$" --category Rust
88
type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?str$" --category Rust

src/etc/lldb_providers.py

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
eBasicTypeLong,
1010
eBasicTypeUnsignedLong,
1111
eBasicTypeUnsignedChar,
12+
eFormatChar,
1213
)
1314

1415
# from lldb.formatters import Logger
@@ -143,11 +144,32 @@ def vec_to_string(vec: SBValue) -> str:
143144
)
144145

145146

146-
def StdStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
147-
# logger = Logger.Logger()
148-
# logger >> "[StdStringSummaryProvider] for " + str(valobj.GetName())
149-
vec = valobj.GetChildAtIndex(0)
150-
return '"%s"' % vec_to_string(vec)
147+
def StdStringSummaryProvider(valobj, dict):
148+
inner_vec = (
149+
valobj.GetNonSyntheticValue()
150+
.GetChildMemberWithName("vec")
151+
.GetNonSyntheticValue()
152+
)
153+
154+
pointer = (
155+
inner_vec.GetChildMemberWithName("buf")
156+
.GetChildMemberWithName("inner")
157+
.GetChildMemberWithName("ptr")
158+
.GetChildMemberWithName("pointer")
159+
.GetChildMemberWithName("pointer")
160+
)
161+
162+
length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned()
163+
164+
if length <= 0:
165+
return ""
166+
error = SBError()
167+
process = pointer.GetProcess()
168+
data = process.ReadMemory(pointer.GetValueAsUnsigned(), length, error)
169+
if error.Success():
170+
return '"' + data.decode("utf8", "replace") + '"'
171+
else:
172+
raise Exception("ReadMemory error: %s", error.GetCString())
151173

152174

153175
def StdOsStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
@@ -266,6 +288,48 @@ def has_children(self) -> bool:
266288
return True
267289

268290

291+
class StdStringSyntheticProvider:
292+
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
293+
self.valobj = valobj
294+
self.update()
295+
296+
def update(self):
297+
inner_vec = self.valobj.GetChildMemberWithName("vec").GetNonSyntheticValue()
298+
self.data_ptr = (
299+
inner_vec.GetChildMemberWithName("buf")
300+
.GetChildMemberWithName("inner")
301+
.GetChildMemberWithName("ptr")
302+
.GetChildMemberWithName("pointer")
303+
.GetChildMemberWithName("pointer")
304+
)
305+
self.length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned()
306+
self.element_type = self.data_ptr.GetType().GetPointeeType()
307+
308+
def has_children(self) -> bool:
309+
return True
310+
311+
def num_children(self) -> int:
312+
return self.length
313+
314+
def get_child_index(self, name: str) -> int:
315+
index = name.lstrip("[").rstrip("]")
316+
if index.isdigit():
317+
return int(index)
318+
319+
return -1
320+
321+
def get_child_at_index(self, index: int) -> SBValue:
322+
if not 0 <= index < self.length:
323+
return None
324+
start = self.data_ptr.GetValueAsUnsigned()
325+
address = start + index
326+
element = self.data_ptr.CreateValueFromAddress(
327+
f"[{index}]", address, self.element_type
328+
)
329+
element.SetFormat(eFormatChar)
330+
return element
331+
332+
269333
class MSVCStrSyntheticProvider:
270334
__slots__ = ["valobj", "data_ptr", "length"]
271335

@@ -699,6 +763,21 @@ def update(self):
699763
)
700764

701765
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
766+
767+
if not self.element_type.IsValid():
768+
# annoyingly, vec's constituent type isn't guaranteed to be contained anywhere useful.
769+
# Some functions have it, but those functions only exist in binary when they're used.
770+
# that means it's time for string-based garbage.
771+
772+
# acquire the first generic parameter via its type name
773+
_, _, end = self.valobj.GetTypeName().partition("<")
774+
element_name, _, _ = end.partition(",")
775+
776+
# this works even for built-in rust types like `u32` because internally it's just a
777+
# `typedef` i really REALLY wish there was a better way to do this, but at the moment
778+
# LLDB flat out ignores template parameters due to piggybacking off of TypeSystemClang.
779+
self.element_type = self.valobj.target.FindFirstType(element_name)
780+
702781
self.element_type_size = self.element_type.GetByteSize()
703782

704783
def has_children(self) -> bool:

0 commit comments

Comments
 (0)