From 4d177a1f400549b6c8bb28bc47a8da0594675df2 Mon Sep 17 00:00:00 2001 From: naruse Date: Sat, 27 May 2017 17:04:31 +0000 Subject: Initial commit of LLDB port of debug utility git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58927 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- misc/lldb_cruby.py | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 misc/lldb_cruby.py (limited to 'misc') diff --git a/misc/lldb_cruby.py b/misc/lldb_cruby.py new file mode 100644 index 0000000000..132a5dd5ea --- /dev/null +++ b/misc/lldb_cruby.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +#coding: utf-8 +# +# Usage: run `command script import -r misc/lldb_cruby.py` on LLDB +# + +import lldb +import commands +import os +import shlex + +RUBY_T_NONE = 0x00 + +RUBY_T_OBJECT = 0x01 +RUBY_T_CLASS = 0x02 +RUBY_T_MODULE = 0x03 +RUBY_T_FLOAT = 0x04 +RUBY_T_STRING = 0x05 +RUBY_T_REGEXP = 0x06 +RUBY_T_ARRAY = 0x07 +RUBY_T_HASH = 0x08 +RUBY_T_STRUCT = 0x09 +RUBY_T_BIGNUM = 0x0a +RUBY_T_FILE = 0x0b +RUBY_T_DATA = 0x0c +RUBY_T_MATCH = 0x0d +RUBY_T_COMPLEX = 0x0e +RUBY_T_RATIONAL = 0x0f + +RUBY_T_NIL = 0x11 +RUBY_T_TRUE = 0x12 +RUBY_T_FALSE = 0x13 +RUBY_T_SYMBOL = 0x14 +RUBY_T_FIXNUM = 0x15 +RUBY_T_UNDEF = 0x16 + +RUBY_T_IMEMO = 0x1a +RUBY_T_NODE = 0x1b +RUBY_T_ICLASS = 0x1c +RUBY_T_ZOMBIE = 0x1d + +RUBY_T_MASK = 0x1f + + +RUBY_FL_WB_PROTECTED = (1<<5) +RUBY_FL_PROMOTED0 = (1<<5) +RUBY_FL_PROMOTED1 = (1<<6) +RUBY_FL_PROMOTED = RUBY_FL_PROMOTED0|RUBY_FL_PROMOTED1 +RUBY_FL_FINALIZE = (1<<7) +RUBY_FL_TAINT = (1<<8) +RUBY_FL_UNTRUSTED = RUBY_FL_TAINT +RUBY_FL_EXIVAR = (1<<10) +RUBY_FL_FREEZE = (1<<11) + +RUBY_FL_USHIFT = 12 + +RUBY_FL_USER0 = (1<<(RUBY_FL_USHIFT+0)) +RUBY_FL_USER1 = (1<<(RUBY_FL_USHIFT+1)) +RUBY_FL_USER2 = (1<<(RUBY_FL_USHIFT+2)) +RUBY_FL_USER3 = (1<<(RUBY_FL_USHIFT+3)) +RUBY_FL_USER4 = (1<<(RUBY_FL_USHIFT+4)) +RUBY_FL_USER5 = (1<<(RUBY_FL_USHIFT+5)) +RUBY_FL_USER6 = (1<<(RUBY_FL_USHIFT+6)) +RUBY_FL_USER7 = (1<<(RUBY_FL_USHIFT+7)) +RUBY_FL_USER8 = (1<<(RUBY_FL_USHIFT+8)) +RUBY_FL_USER9 = (1<<(RUBY_FL_USHIFT+9)) +RUBY_FL_USER10 = (1<<(RUBY_FL_USHIFT+10)) +RUBY_FL_USER11 = (1<<(RUBY_FL_USHIFT+11)) +RUBY_FL_USER12 = (1<<(RUBY_FL_USHIFT+12)) +RUBY_FL_USER13 = (1<<(RUBY_FL_USHIFT+13)) +RUBY_FL_USER14 = (1<<(RUBY_FL_USHIFT+14)) +RUBY_FL_USER15 = (1<<(RUBY_FL_USHIFT+15)) +RUBY_FL_USER16 = (1<<(RUBY_FL_USHIFT+16)) +RUBY_FL_USER17 = (1<<(RUBY_FL_USHIFT+17)) +RUBY_FL_USER18 = (1<<(RUBY_FL_USHIFT+18)) +RUBY_FL_USER19 = (1<<(RUBY_FL_USHIFT+19)) + +RSTRING_NOEMBED = RUBY_FL_USER1 + +def lldb_rp(debugger, command, result, internal_dict): + target = debugger.GetSelectedTarget() + process = target.GetProcess() + thread = process.GetSelectedThread() + frame = thread.GetSelectedFrame() + val = frame.EvaluateExpression(command) + num = val.GetValueAsSigned() + if num == 0: + print('false') + elif num == 0x14: + print('nil') + elif num == 8: + print('nil') + elif num == 0x34: + print('Qundef') + elif num & 1 != 0: + print(num >> 1) + else: + tRBasic = target.FindFirstType("struct RBasic").GetPointerType() + val = val.Cast(tRBasic) + flags = val.GetValueForExpressionPath("->flags").GetValueAsUnsigned() + flType = flags & RUBY_T_MASK + if flType == RUBY_T_STRING: + tRString = target.FindFirstType("struct RString").GetPointerType() + val = val.Cast(tRString) + if flags & RSTRING_NOEMBED: + print(val.GetValueForExpressionPath("->as.heap")) + else: + print(val.GetValueForExpressionPath("->as.ary")) + elif flType == RUBY_T_ARRAY: + tRArray = target.FindFirstType("struct RArray").GetPointerType() + val = val.Cast(tRArray) + if flags & RUBY_FL_USER1: + len = ((flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3)) + print("T_ARRAY: len=%d (embed)" % len) + if len == 0: + print "{(empty)}" + else: + print(val.GetValueForExpressionPath("->as.ary")) + else: + len = val.GetValueForExpressionPath("->as.heap.len").GetValueAsSigned() + print("T_ARRAY: len=%d " % len) + #print(val.GetValueForExpressionPath("->as.heap")) + if flags & RUBY_FL_USER2: + shared = val.GetValueForExpressionPath("->as.heap.aux.shared").GetValueAsUnsigned() + print "(shared) shared=%016x " % shared + else: + capa = val.GetValueForExpressionPath("->as.heap.aux.capa").GetValueAsSigned() + print "(ownership) capa=%d " % capa + if len == 0: + print "{(empty)}" + else: + debugger.HandleCommand("expression -Z %d -fx -- (const VALUE*)((struct RArray*)%d)->as.heap.ptr" % (len, val.GetValueAsUnsigned())) + debugger.HandleCommand("p (struct RArray *) %0#x" % val.GetValueAsUnsigned()) + + +def __lldb_init_module(debugger, internal_dict): + debugger.HandleCommand("command script add -f lldb_cruby.lldb_rp rp") + print "lldb scripts for ruby has been installed." -- cgit v1.2.3