/usr/lib/mono/lldb/mono.py is in mono-devel 4.6.2.7+dfsg-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | #
# Author: Zoltan Varga (vargaz@gmail.com)
# License: MIT/X11
#
#
# This is a mono support mode for lldb
#
# Comments about the lldb python api:
# - there are no accessors, i.e. valobj["name"]
# - http://lldb.llvm.org/python_reference/index.html seems to be outdated
# - there is no autoload support, i.e. can't load this file automatically
# when 'mono' is the debugger target.
import lldb
# FIXME: Generate enums from runtime enums
MONO_TYPE_END = 0x00
MONO_TYPE_VOID = 0x01
MONO_TYPE_BOOLEAN = 0x02
MONO_TYPE_CHAR = 0x03
MONO_TYPE_I1 = 0x04
MONO_TYPE_U1 = 0x05
MONO_TYPE_I2 = 0x06
MONO_TYPE_U2 = 0x07
MONO_TYPE_I4 = 0x08
MONO_TYPE_U4 = 0x09
MONO_TYPE_I8 = 0x0a
MONO_TYPE_U8 = 0x0b
MONO_TYPE_R4 = 0x0c
MONO_TYPE_R8 = 0x0d
MONO_TYPE_STRING = 0x0e
MONO_TYPE_PTR = 0x0f
MONO_TYPE_BYREF = 0x10
MONO_TYPE_VALUETYPE = 0x11
MONO_TYPE_CLASS = 0x12
MONO_TYPE_VAR = 0x13
MONO_TYPE_ARRAY = 0x14
MONO_TYPE_GENERICINST= 0x15
MONO_TYPE_TYPEDBYREF = 0x16
MONO_TYPE_I = 0x18
MONO_TYPE_U = 0x19
MONO_TYPE_FNPTR = 0x1b
MONO_TYPE_OBJECT = 0x1c
MONO_TYPE_SZARRAY = 0x1d
MONO_TYPE_MVAR = 0x1e
primitive_type_names = {
MONO_TYPE_BOOLEAN : "bool",
MONO_TYPE_CHAR : "char",
MONO_TYPE_I1 : "sbyte",
MONO_TYPE_U1 : "byte",
MONO_TYPE_I2 : "short",
MONO_TYPE_U2 : "ushort",
MONO_TYPE_I4 : "int",
MONO_TYPE_U4 : "uint",
MONO_TYPE_I8 : "long",
MONO_TYPE_U8 : "ulong",
MONO_TYPE_R4 : "float",
MONO_TYPE_R8 : "double",
MONO_TYPE_STRING : "string"
}
#
# Helper functions for working with the lldb python api
#
def member(val, member_name):
return val.GetChildMemberWithName (member_name)
def string_member(val, member_name):
return val.GetChildMemberWithName (member_name).GetSummary ()[1:-1]
def isnull(val):
return val.deref.addr.GetOffset () == 0
def stringify_class_name(ns, name):
if ns == "System":
if name == "Byte":
return "byte"
if name == "String":
return "string"
if ns == "":
return name
else:
return "{0}.{1}".format (ns, name)
#
# Pretty printers for mono runtime types
#
def stringify_type (type):
"Print a MonoType structure"
ttype = member(type, "type").GetValueAsUnsigned()
if primitive_type_names.has_key (ttype):
return primitive_type_names [ttype]
else:
return "<MonoTypeEnum 0x{0:x}>".format (ttype)
def stringify_ginst (ginst):
"Print a MonoGenericInst structure"
len = int(member(ginst, "type_argc").GetValue())
argv = member(ginst, "type_argv")
res=""
for i in range(len):
t = argv.GetChildAtIndex(i, False, True)
if i > 0:
res += ", "
res += stringify_type(t)
return res
def print_type(valobj, internal_dict):
type = valobj
if isnull (type):
return ""
return stringify_type (type)
def print_class (valobj, internal_dict):
klass = valobj
if isnull (klass):
return ""
aname = member (member (member (klass, "image"), "assembly"), "aname")
basename = "[{0}]{1}".format (string_member (aname, "name"), (stringify_class_name (string_member (klass, "name_space"), string_member (klass, "name"))))
gclass = member (klass, "generic_class")
if not isnull (gclass):
ginst = member (member (gclass, "context"), "class_inst")
return "{0}<{1}>".format (basename, stringify_ginst (ginst))
return basename
def print_method (valobj, internal_dict):
method = valobj
if isnull (method):
return ""
klass = member (method, "klass")
return "{0}:{1}()".format (print_class (klass, None), string_member (valobj, "name"))
def print_domain(valobj, internal_dict):
domain = valobj
if isnull (domain):
return ""
target = domain.target
root = target.FindFirstGlobalVariable("mono_root_domain")
name = string_member (domain, "friendly_name")
if root.IsValid () and root.deref.addr.GetOffset () == root.deref.addr.GetOffset ():
return "[root]"
else:
return "[{0}]".format (name)
def print_object(valobj, internal_dict):
obj = valobj
if isnull (obj):
return ""
domain = member (member (obj, "vtable"), "domain")
klass = member (member (obj, "vtable"), "klass")
return print_domain (domain, None) + print_class (klass, None)
# Register pretty printers
# FIXME: This cannot pick up the methods define in this module, leading to warnings
lldb.debugger.HandleCommand ("type summary add -w mono -F mono.print_method MonoMethod")
lldb.debugger.HandleCommand ("type summary add -w mono -F mono.print_class MonoClass")
lldb.debugger.HandleCommand ("type summary add -w mono -F mono.print_type MonoType")
lldb.debugger.HandleCommand ("type summary add -w mono -F mono.print_domain MonoDomain")
lldb.debugger.HandleCommand ("type summary add -w mono -F mono.print_object MonoObject")
lldb.debugger.HandleCommand ("type category enable mono")
# Helper commands for runtime debugging
# These resume the target
# Print the method at the current ip
lldb.debugger.HandleCommand ("command alias pip p mono_print_method_from_ip((void*)$pc)")
# Print the method at the provided ip
lldb.debugger.HandleCommand ("command regex pmip 's/^$/p mono_print_method_from_ip((void*)$pc)/' 's/(.+)/p mono_print_method_from_ip((void*)(%1))/'")
print "Mono support mode loaded."
|