Files
eepp/projects/scripts/debug/eepp_lldb.py
Martín Lucas Golini 4718a52423 Migrated from robin_hood to unordered_dense (for UnorderedMap and UnorederedSet).
Added support for SmallVector using svector (and we are already using it in a couple of places).
Added debug symbol inspector script for the new SmallVector in project/scripts/debug.
Added tilde support for files and folders passed as parameters from the CLI in ecode (and added FileSystem::expandTilde).
Fixed a bug in "light-dark" parsing.
2026-03-14 15:13:41 -03:00

106 lines
3.5 KiB
Python

import lldb
class EESmallVectorSyntheticProvider:
def __init__(self, valobj, internal_dict):
self.valobj = valobj
self.update()
def update(self):
self.size = 0
self.capacity = 0
self.is_direct = True
self.data_addr = lldb.LLDB_INVALID_ADDRESS
# 1. Get the type of T (e.g., Client*)
self.type_t = self.valobj.GetType().GetTemplateArgumentType(0)
# 2. Find the m_data array
self.m_data = self.valobj.GetChildMemberWithName("m_data")
if not self.m_data.IsValid():
return
process = self.valobj.GetProcess()
addr = self.m_data.GetLoadAddress()
error = lldb.SBError()
if addr == lldb.LLDB_INVALID_ADDRESS or not process.IsValid():
return
# 3. Read the first byte (the discriminator & size)
first_byte = process.ReadUnsignedIntegerFromMemory(addr, 1, error)
self.is_direct = (first_byte & 1) != 0
ptr_size = process.GetAddressByteSize()
if self.is_direct:
self.size = first_byte >> 1
self.capacity = 0 # Implied by N, but not explicitly stored
# Data starts at offset equal to the alignment of T
align_t = self.type_t.GetByteAlign()
if align_t == 0:
align_t = self.type_t.GetByteSize() # Fallback
if align_t == 0:
align_t = ptr_size
self.data_addr = addr + align_t
else:
# 4. Indirect Mode: read the pointer to the heap storage
void_ptr = process.ReadPointerFromMemory(addr, error)
# The storage header contains: size_t m_size, size_t m_capacity
self.size = process.ReadUnsignedIntegerFromMemory(void_ptr, ptr_size, error)
self.capacity = process.ReadUnsignedIntegerFromMemory(
void_ptr + ptr_size, ptr_size, error
)
# Calculate offset_to_data: round_up(sizeof(header), alignment_of_t)
header_size = 2 * ptr_size
align_t = self.type_t.GetByteAlign()
if align_t == 0:
align_t = self.type_t.GetByteSize()
if align_t == 0:
align_t = ptr_size
offset = ((header_size + (align_t - 1)) // align_t) * align_t
self.data_addr = void_ptr + offset
def num_children(self):
return self.size
def get_child_index(self, name):
try:
return int(name.lstrip("[").rstrip("]"))
except:
return -1
def get_child_at_index(self, index):
if index < 0 or index >= self.size:
return None
item_addr = self.data_addr + index * self.type_t.GetByteSize()
return self.valobj.CreateValueFromAddress(f"[{index}]", item_addr, self.type_t)
def has_children(self):
return self.size > 0
def EESmallVectorSummaryProvider(valobj, internal_dict):
provider = EESmallVectorSyntheticProvider(valobj, internal_dict)
if provider.is_direct:
return f"[Direct] size={provider.size}"
else:
return f"[Indirect] size={provider.size}, capacity={provider.capacity}"
def __lldb_init_module(debugger, internal_dict):
# Register the Summary (the text next to the variable)
debugger.HandleCommand(
'type summary add -x "^EE::SmallVector<.+>$" -F eepp_lldb.EESmallVectorSummaryProvider'
)
# Register the Synthetic Children (the expandable array elements)
debugger.HandleCommand(
'type synthetic add -x "^EE::SmallVector<.+>$" -l eepp_lldb.EESmallVectorSyntheticProvider'
)