LLDB: Introduce dump_page helper

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)
This commit is contained in:
Matt Valentine-House 2021-03-16 10:47:35 +00:00 коммит произвёл Aaron Patterson
Родитель 1dca333599
Коммит a47697aa44
1 изменённых файлов: 53 добавлений и 0 удалений

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

@ -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")
@ -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.")