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