mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
lldb: Add Freelist Index to dump_page output
This commit is contained in:
parent
1b2abb6590
commit
c752a35816
Notes:
git
2021-04-27 23:59:16 +09:00
1 changed files with 50 additions and 13 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue