Skip to content

Commit

Permalink
LLDB: Introduce dump_page helper
Browse files Browse the repository at this point in the history
This dumps out object type information for every object on a page in the
form:

bits [LM R ] T_CLASS    [389]: Addr: 0x1007ebcf0 (flags: 0x100000062)
  • Loading branch information
eightbitraptor authored and tenderlove committed Mar 16, 2021
1 parent 1dca333 commit a47697a
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions misc/lldb_cruby.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,57 @@ def dump_bits(target, result, page, object_address, end = "\n"):
check_bits(page, "marking_bits", bitmap_index, bitmap_bit, "R"),
check_bits(page, "wb_unprotected_bits", bitmap_index, bitmap_bit, "U"),
), end=end, file=result)

def dump_page(debugger, command, result, internal_dict):
if not ('RUBY_Qfalse' in globals()):
lldb_init(debugger)

target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()

tHeapPageP = target.FindFirstType("struct heap_page").GetPointerType()
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)

def rb_type(flags, ruby_types):
flType = flags & RUBY_T_MASK
return "%-10s" % (ruby_types.get(flType, ("%0#x" % flType)))

def ruby_types(debugger):
target = debugger.GetSelectedTarget()

types = {}
for enum in target.FindFirstGlobalVariable('ruby_dummy_gdb_enums'):
enum = enum.GetType()
members = enum.GetEnumMembers()
for i in range(0, members.GetSize()):
member = members.GetTypeEnumMemberAtIndex(i)
name = member.GetName()
value = member.GetValueAsUnsigned()

if name.startswith('RUBY_T_'):
types[value] = name.replace('RUBY_', '')

return types

def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("command script add -f lldb_cruby.lldb_rp rp")
debugger.HandleCommand("command script add -f lldb_cruby.count_objects rb_count_objects")
Expand All @@ -534,5 +585,7 @@ def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("command script add -f lldb_cruby.heap_page heap_page")
debugger.HandleCommand("command script add -f lldb_cruby.heap_page_body heap_page_body")
debugger.HandleCommand("command script add -f lldb_cruby.rb_backtrace rbbt")
debugger.HandleCommand("command script add -f lldb_cruby.dump_page dump_page")

lldb_init(debugger)
print("lldb scripts for ruby has been installed.")

0 comments on commit a47697a

Please sign in to comment.