From 5a451c4b1f7f7bbd6607cb3f32f3ddd98e064971 Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Thu, 29 Apr 2021 17:02:02 +0100 Subject: lldb: Warn when attempting to dump invalid pages --- misc/lldb_cruby.py | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'misc') diff --git a/misc/lldb_cruby.py b/misc/lldb_cruby.py index 2a33ebfb6f..b694313ff4 100755 --- a/misc/lldb_cruby.py +++ b/misc/lldb_cruby.py @@ -13,6 +13,8 @@ import shlex HEAP_PAGE_ALIGN_LOG = 14 HEAP_PAGE_ALIGN_MASK = (~(~0 << HEAP_PAGE_ALIGN_LOG)) +HEAP_PAGE_ALIGN = (1 << HEAP_PAGE_ALIGN_LOG) +HEAP_PAGE_SIZE = HEAP_PAGE_ALIGN class BackTrace: VM_FRAME_MAGIC_METHOD = 0x11110001 @@ -537,6 +539,16 @@ class HeapPageIter: self.tRBasic = target.FindFirstType("struct RBasic") self.tRValue = target.FindFirstType("struct RVALUE") + def is_valid(self): + heap_page_header_size = self.target.FindFirstType("struct heap_page_header").GetByteSize() + rvalue_size = self.tRValue.GetByteSize() + heap_page_obj_limit = (HEAP_PAGE_SIZE - heap_page_header_size)/rvalue_size + + if (self.num_slots > heap_page_obj_limit) or (self.num_slots < heap_page_obj_limit - 1): + return False + else: + return True + def __iter__(self): return self @@ -568,24 +580,30 @@ def dump_page_internal(page, target, process, thread, frame, result, debugger, h 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 = ' ' + page_iter = HeapPageIter(page, target) + if page_iter.is_valid(): + for (page_index, obj_addr, obj) in page_iter: + 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) + 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) - if highlight == obj_addr: - result_str = ' '.join([result_str, "<<<<<"]) + if highlight == obj_addr: + result_str = ' '.join([result_str, "<<<<<"]) + + print(result_str, file=result) + else: + print("%s is not a valid heap page" % page, file=result) - print(result_str, file=result) def dump_page(debugger, command, result, internal_dict): -- cgit v1.2.3