summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorMatt Valentine-House <matt@eightbitraptor.com>2021-04-27 12:13:29 +0100
committerPeter Zhu <peter@peterzhu.ca>2021-04-27 10:58:49 -0400
commitc752a35816c64c0eef3324a860ad4a535fb8ff2b (patch)
treedbccee7a0e563b64108d1ef2622c2d91ca4e5130 /misc
parent1b2abb6590a653cb7b31d73c42edbaf2d0617b27 (diff)
lldb: Add Freelist Index to dump_page output
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4420
Diffstat (limited to 'misc')
-rwxr-xr-xmisc/lldb_cruby.py61
1 files changed, 49 insertions, 12 deletions
diff --git a/misc/lldb_cruby.py b/misc/lldb_cruby.py
index e0cf53760f..748d8aacf6 100755
--- a/misc/lldb_cruby.py
+++ b/misc/lldb_cruby.py
@@ -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")
+ ruby_type_map = ruby_types(debugger)
- obj_address = page.GetChildMemberWithName('start').GetValueAsUnsigned();
- num_slots = page.GetChildMemberWithName('total_slots').unsigned
+ freelist = []
+ fl_start = page.GetChildMemberWithName('freelist').GetValueAsUnsigned()
+ tRVALUE = target.FindFirstType("struct RVALUE")
- ruby_type_map = ruby_types(debugger)
+ 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)
- 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)
def rb_type(flags, ruby_types):
flType = flags & RUBY_T_MASK