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
|
"""lldb data formatters for clang classes.
Usage
--
import this file in your ~/.lldbinit by adding this line:
command script import /path/to/ClangDataFormat.py
After that, instead of getting this:
(lldb) p Tok.Loc
(clang::SourceLocation) $0 = {
(unsigned int) ID = 123582
}
you'll get:
(lldb) p Tok.Loc
(clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file)
"""
import lldb
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation")
def SourceLocation_summary(srcloc, internal_dict):
return SourceLocation(srcloc).summary()
class SourceLocation(object):
def __init__(self, srcloc):
self.srcloc = srcloc
def offset(self):
return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned()
def isMacro(self):
return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned()
def getPrint(self, srcmgr_path):
print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path)
return print_str.GetSummary()
def summary(self):
desc = "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file")
srcmgr_path = findObjectExpressionPath("clang::SourceManager", lldb.frame)
if srcmgr_path:
desc = self.getPrint(srcmgr_path) + " " + desc
return desc
# Key is a (function address, type name) tuple, value is the expression path for
# an object with such a type name from inside that function.
FramePathMapCache = {}
def findObjectExpressionPath(typename, frame):
func_addr = frame.GetFunction().GetStartAddress().GetFileAddress()
key = (func_addr, typename)
try:
return FramePathMapCache[key]
except KeyError:
#print "CACHE MISS"
path = None
obj = findObject(typename, frame)
if obj:
path = getExpressionPath(obj)
FramePathMapCache[key] = path
return path
def findObject(typename, frame):
def getTypename(value):
# FIXME: lldb should provide something like getBaseType
ty = value.GetType()
if ty.IsPointerType() or ty.IsReferenceType():
return ty.GetPointeeType().GetName()
return ty.GetName()
def searchForType(value, searched):
tyname = getTypename(value)
#print "SEARCH:", getExpressionPath(value), value.GetType().GetName()
if tyname == typename:
return value
ty = value.GetType()
if not (ty.IsPointerType() or
ty.IsReferenceType() or
# FIXME: lldb should provide something like getCanonicalType
tyname.startswith("llvm::IntrusiveRefCntPtr<") or
tyname.startswith("llvm::OwningPtr<")):
return None
# FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead,
# and not the canonical one unfortunately.
if tyname in searched:
return None
searched.add(tyname)
for i in range(value.GetNumChildren()):
child = value.GetChildAtIndex(i, 0, False)
found = searchForType(child, searched)
if found:
return found
searched = set()
value_list = frame.GetVariables(True, True, True, True)
for val in value_list:
found = searchForType(val, searched)
if found:
return found if not found.TypeIsPointerType() else found.Dereference()
def getValueFromExpression(val, expr):
return lldb.frame.EvaluateExpression(getExpressionPath(val) + expr)
def getExpressionPath(val):
stream = lldb.SBStream()
val.GetExpressionPath(stream)
return stream.GetData()
|