lldb: Add Freelist Index to dump_page output

This commit is contained in:
Matt Valentine-House 2021-04-27 12:13:29 +01:00 коммит произвёл Peter Zhu
Родитель 1b2abb6590
Коммит c752a35816
1 изменённых файлов: 50 добавлений и 13 удалений

Просмотреть файл

@ -527,6 +527,31 @@ def dump_bits(target, result, page, object_address, end = "\n"):
check_bits(page, "wb_unprotected_bits", bitmap_index, bitmap_bit, "U"),
), end=end, file=result)
class HeapPageIter:
def __init__(self, page, target):
self.page = page
self.target = target
self.start = page.GetChildMemberWithName('start').GetValueAsUnsigned();
self.num_slots = page.GetChildMemberWithName('total_slots').unsigned
self.counter = 0
self.tRBasic = target.FindFirstType("struct RBasic")
self.tRValue = target.FindFirstType("struct RVALUE")
def __iter__(self):
return self
def __next__(self):
if self.counter < self.num_slots:
obj_addr_i = self.start + (self.counter * self.tRValue.GetByteSize())
obj_addr = lldb.SBAddress(obj_addr_i, self.target)
slot_info = (self.counter, obj_addr_i, self.target.CreateValueFromAddress("object", obj_addr, self.tRBasic))
self.counter += 1
return slot_info
else:
raise StopIteration
def dump_page(debugger, command, result, internal_dict):
if not ('RUBY_Qfalse' in globals()):
lldb_init(debugger)
@ -540,21 +565,33 @@ def dump_page(debugger, command, result, internal_dict):
page = frame.EvaluateExpression(command)
page = page.Cast(tHeapPageP)
tRBasic = target.FindFirstType("struct RBasic")
tRValue = target.FindFirstType("struct RVALUE")
obj_address = page.GetChildMemberWithName('start').GetValueAsUnsigned();
num_slots = page.GetChildMemberWithName('total_slots').unsigned
ruby_type_map = ruby_types(debugger)
for j in range(0, num_slots):
offset = obj_address + (j * tRValue.GetByteSize())
obj_addr = lldb.SBAddress(offset, target)
p = target.CreateValueFromAddress("object", obj_addr, tRBasic)
dump_bits(target, result, page, offset, end = " ")
flags = p.GetChildMemberWithName('flags').GetValueAsUnsigned()
print("%s [%3d]: Addr: %0#x (flags: %0#x)" % (rb_type(flags, ruby_type_map), j, offset, flags), file=result)
freelist = []
fl_start = page.GetChildMemberWithName('freelist').GetValueAsUnsigned()
tRVALUE = target.FindFirstType("struct RVALUE")
while fl_start > 0:
freelist.append(fl_start)
obj_addr = lldb.SBAddress(fl_start, target)
obj = target.CreateValueFromAddress("object", obj_addr, tRVALUE)
fl_start = obj.GetChildMemberWithName("as").GetChildMemberWithName("free").GetChildMemberWithName("next").GetValueAsUnsigned()
for (page_index, obj_addr, obj) in HeapPageIter(page, target):
dump_bits(target, result, page, obj_addr, end= " ")
flags = obj.GetChildMemberWithName('flags').GetValueAsUnsigned()
flType = flags & RUBY_T_MASK
flidx = ' '
if flType == RUBY_T_NONE:
try:
flidx = "%3d" % freelist.index(obj_addr)
except ValueError:
flidx = ' '
result_str = "%s idx: [%3d] freelist_idx: {%s} Addr: %0#x (flags: %0#x)" % (rb_type(flags, ruby_type_map), page_index, flidx, obj_addr, flags)
print(result_str, file=result)
def rb_type(flags, ruby_types):
flType = flags & RUBY_T_MASK