mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
139 lines
4.5 KiB
Python
139 lines
4.5 KiB
Python
|
#!/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."
|