aboutsummaryrefslogtreecommitdiffstats
path: root/misc
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-27 17:04:31 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-27 17:04:31 +0000
commit4d177a1f400549b6c8bb28bc47a8da0594675df2 (patch)
treee4f04ff7c51b5bfa78056097529148f56821e065 /misc
parent1d9030a1073bbc6d8fcec6cd37e3c6ea3b005d8a (diff)
downloadruby-4d177a1f400549b6c8bb28bc47a8da0594675df2.tar.gz
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
Diffstat (limited to 'misc')
-rw-r--r--misc/lldb_cruby.py138
1 files changed, 138 insertions, 0 deletions
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."