diff options
Diffstat (limited to 'misc/lldb_rb')
| -rw-r--r-- | misc/lldb_rb/commands/heap_page_command.py | 5 | ||||
| -rw-r--r-- | misc/lldb_rb/commands/print_flags_command.py | 6 | ||||
| -rw-r--r-- | misc/lldb_rb/lldb_interface.py | 11 | ||||
| -rw-r--r-- | misc/lldb_rb/rb_heap_structs.py | 19 | ||||
| -rw-r--r-- | misc/lldb_rb/utils.py | 35 |
5 files changed, 45 insertions, 31 deletions
diff --git a/misc/lldb_rb/commands/heap_page_command.py b/misc/lldb_rb/commands/heap_page_command.py index b56a3eae4e..2eed3c3bee 100644 --- a/misc/lldb_rb/commands/heap_page_command.py +++ b/misc/lldb_rb/commands/heap_page_command.py @@ -8,14 +8,15 @@ class HeapPageCommand(RbBaseCommand): help_string = "prints out 'struct heap_page' for a VALUE pointer in the page" def call(self, debugger, command, exe_ctx, result): + self.result = result self.t_heap_page_body = self.target.FindFirstType("struct heap_page_body") self.t_heap_page_ptr = self.target.FindFirstType("struct heap_page").GetPointerType() page = self._get_page(self.frame.EvaluateExpression(command)) page.Cast(self.t_heap_page_ptr) - self._append_expression(debugger, "(struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result) - self._append_expression(debugger, "*(struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result) + self._append_expression("(struct heap_page *) %0#x" % page.GetValueAsUnsigned()) + self._append_expression("*(struct heap_page *) %0#x" % page.GetValueAsUnsigned()) def _get_page(self, val): addr = val.GetValueAsUnsigned() diff --git a/misc/lldb_rb/commands/print_flags_command.py b/misc/lldb_rb/commands/print_flags_command.py index 00da4834bf..bc494ae01a 100644 --- a/misc/lldb_rb/commands/print_flags_command.py +++ b/misc/lldb_rb/commands/print_flags_command.py @@ -11,13 +11,13 @@ class PrintFlagsCommand(RbBaseCommand): # call is where our command logic will be implemented def call(self, debugger, command, exe_ctx, result): - rclass_t = self.target.FindFirstType("struct RBasic") + rclass_t = self.target.FindFirstType("::RBasic") rcass_ptr = self.target.EvaluateExpression(command).Cast(rclass_t.GetPointerType()) obj_flags = rcass_ptr.GetValueForExpressionPath("->flags").GetValueAsUnsigned() flags = [ - "RUBY_FL_WB_PROTECTED", "RUBY_FL_PROMOTED0", "RUBY_FL_PROMOTED1", "RUBY_FL_FINALIZE", - "RUBY_FL_SHAREABLE", "RUBY_FL_EXIVAR", "RUBY_FL_FREEZE", + "RUBY_FL_WB_PROTECTED", "RUBY_FL_PROMOTED", "RUBY_FL_FINALIZE", + "RUBY_FL_SHAREABLE", "RUBY_FL_FREEZE", "RUBY_FL_USER0", "RUBY_FL_USER1", "RUBY_FL_USER2", "RUBY_FL_USER3", "RUBY_FL_USER4", "RUBY_FL_USER5", "RUBY_FL_USER6", "RUBY_FL_USER7", "RUBY_FL_USER8", "RUBY_FL_USER9", "RUBY_FL_USER10", "RUBY_FL_USER11", "RUBY_FL_USER12", "RUBY_FL_USER13", "RUBY_FL_USER14", diff --git a/misc/lldb_rb/lldb_interface.py b/misc/lldb_rb/lldb_interface.py index 785a54b3e3..25930b2e16 100644 --- a/misc/lldb_rb/lldb_interface.py +++ b/misc/lldb_rb/lldb_interface.py @@ -5,3 +5,14 @@ class LLDBInterface: self.process = self.target.GetProcess() self.thread = self.process.GetSelectedThread() self.frame = self.thread.GetSelectedFrame() + + def _append_command_output(self, command): + output1 = self.result.GetOutput() + self.debugger.GetCommandInterpreter().HandleCommand(command, self.result) + output2 = self.result.GetOutput() + self.result.Clear() + self.result.write(output1) + self.result.write(output2) + + def _append_expression(self, expression): + self._append_command_output("expression " + expression) diff --git a/misc/lldb_rb/rb_heap_structs.py b/misc/lldb_rb/rb_heap_structs.py index 86b38dbbbd..798b838080 100644 --- a/misc/lldb_rb/rb_heap_structs.py +++ b/misc/lldb_rb/rb_heap_structs.py @@ -1,4 +1,5 @@ import lldb +import math from lldb_rb.lldb_interface import LLDBInterface from lldb_rb.constants import * @@ -50,8 +51,7 @@ class RbObject(LLDBInterface): self.flUser9 = self.ruby_globals["RUBY_FL_USER9"] self.flUshift = self.ruby_globals["RUBY_FL_USHIFT"] - self.tRBasic = self.target.FindFirstType("struct RBasic").GetPointerType() - self.tRValue = self.target.FindFirstType("struct RVALUE") + self.tRBasic = self.target.FindFirstType("::RBasic").GetPointerType() self.val = ptr.Cast(self.tRBasic) self.page = HeapPage(self.debugger, self.val) @@ -70,10 +70,12 @@ class RbObject(LLDBInterface): return ' ' def dump_bits(self, result, end = "\n"): - tRValue = self.target.FindFirstType("struct RVALUE") tUintPtr = self.target.FindFirstType("uintptr_t") # bits_t - num_in_page = (self.val.GetValueAsUnsigned() & HEAP_PAGE_ALIGN_MASK) // tRValue.GetByteSize(); + slot_size = self.page.to_heap_page_struct().GetChildMemberWithName("heap").GetChildMemberWithName("slot_size").unsigned + byte_size = 40 ** math.floor(math.log(slot_size, 40)) + + num_in_page = (self.val.GetValueAsUnsigned() & HEAP_PAGE_ALIGN_MASK) // byte_size; bits_bitlength = tUintPtr.GetByteSize() * 8 bitmap_index = num_in_page // bits_bitlength bitmap_offset = num_in_page & (bits_bitlength - 1) @@ -109,7 +111,14 @@ class RbObject(LLDBInterface): return False def as_type(self, type_name): - return self.val.Cast(self.tRValue.GetPointerType()).GetValueForExpressionPath("->as."+type_name) + if type_name == "array": + tRarray = self.target.FindFirstType("struct RArray") + return self.val.Cast(tRarray.GetPointerType()) + elif type_name == "bignum": + tRbignum = self.target.FindFirstType("struct RBignum") + return self.val.Cast(tRbignum.GetPointerType()) + else: + print("as_type is not implemented for:", type_name) def ary_ptr(self): rval = self.as_type("array") diff --git a/misc/lldb_rb/utils.py b/misc/lldb_rb/utils.py index a6bbd385cd..a2bcedc328 100644 --- a/misc/lldb_rb/utils.py +++ b/misc/lldb_rb/utils.py @@ -8,17 +8,6 @@ class RbInspector(LLDBInterface): self.result = result self.ruby_globals = ruby_globals - def _append_command_output(self, command): - output1 = self.result.GetOutput() - self.debugger.GetCommandInterpreter().HandleCommand(command, self.result) - output2 = self.result.GetOutput() - self.result.Clear() - self.result.write(output1) - self.result.write(output2) - - def _append_expression(self, expression): - self._append_command_output("expression " + expression) - def string2cstr(self, rstring): """Returns the pointer to the C-string in the given String object""" if rstring.TypeIsPointerType(): @@ -247,16 +236,20 @@ class RbInspector(LLDBInterface): elif rval.is_type("RUBY_T_DATA"): tRTypedData = self.target.FindFirstType("struct RTypedData").GetPointerType() val = val.Cast(tRTypedData) - flag = val.GetValueForExpressionPath("->typed_flag") - if flag.GetValueAsUnsigned() == 1: - print("T_DATA: %s" % - val.GetValueForExpressionPath("->type->wrap_struct_name"), - file=self.result) - self._append_expression("*(struct RTypedData *) %0#x" % val.GetValueAsUnsigned()) - else: - print("T_DATA:", file=self.result) - self._append_expression("*(struct RData *) %0#x" % val.GetValueAsUnsigned()) + type = val.GetValueForExpressionPath("->type").GetValueAsUnsigned() + embed = (type & 1) + if embed: + flaginfo += "[EMBED] " + type = self.frame.EvaluateExpression("(rb_data_type_t *)%0#x" % (type & ~1)) + print("T_DATA: %s%s" % + (flaginfo, type.GetValueForExpressionPath("->wrap_struct_name")), + file=self.result) + print("%s", type.Dereference(), file=self.result) + ptr = val.GetValueForExpressionPath("->data") + if embed: + ptr = ptr.AddressOf() + self._append_expression("(void *)%0#x" % ptr.GetValueAsUnsigned()) elif rval.is_type("RUBY_T_IMEMO"): imemo_type = ((rval.flags >> self.ruby_globals["RUBY_FL_USHIFT"]) @@ -290,7 +283,7 @@ class RbInspector(LLDBInterface): # if val.GetType() != tRNode: does not work for unknown reason - if val.GetType().GetPointeeType().name != "NODE": + if val.GetType().GetPointeeType().GetCanonicalType().name != "RNode": return False rbNodeTypeMask = self.ruby_globals["RUBY_NODE_TYPEMASK"] |
