blob: bf4f2c6bbb7c274a95b1d49a046ac41861aa7715 [file] [log] [blame]
Enrico Granata3f1052b2012-03-13 21:52:00 +00001"""
2LLDB AppKit formatters
3
4part of The LLVM Compiler Infrastructure
5This file is distributed under the University of Illinois Open Source
6License. See LICENSE.TXT for details.
7"""
Enrico Granata3467d802012-09-04 18:47:54 +00008# example summary provider for NSData
9# the real summary is now C++ code built into LLDB
Enrico Granataeb4a4792012-02-23 23:10:27 +000010import lldb
11import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000012import lldb.runtime.objc.objc_runtime
13import lldb.formatters.metrics
14import lldb.formatters.Logger
Enrico Granataeb4a4792012-02-23 23:10:27 +000015
Enrico Granata28399ad2012-04-25 01:39:27 +000016statistics = lldb.formatters.metrics.Metrics()
Enrico Granataeb4a4792012-02-23 23:10:27 +000017statistics.add_metric('invalid_isa')
18statistics.add_metric('invalid_pointer')
19statistics.add_metric('unknown_class')
20statistics.add_metric('code_notrun')
21
22# despite the similary to synthetic children providers, these classes are not
23# trying to provide anything but the length for an NSData, so they need not
24# obey the interface specification for synthetic children providers
Kate Stoneb9c1b512016-09-06 20:57:50 +000025
26
Enrico Granataeb4a4792012-02-23 23:10:27 +000027class NSConcreteData_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000028
Kate Stoneb9c1b512016-09-06 20:57:50 +000029 def adjust_for_architecture(self):
30 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032 def __init__(self, valobj, params):
33 logger = lldb.formatters.Logger.Logger()
34 logger >> "NSConcreteData_SummaryProvider __init__"
35 self.valobj = valobj
36 self.sys_params = params
37 if not(self.sys_params.types_cache.NSUInteger):
38 if self.sys_params.is_64_bit:
39 self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
40 ).GetBasicType(lldb.eBasicTypeUnsignedLong)
41 else:
42 self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
43 ).GetBasicType(lldb.eBasicTypeUnsignedInt)
44 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000045
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 def update(self):
47 self.adjust_for_architecture()
Enrico Granataeb4a4792012-02-23 23:10:27 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 # one pointer is the ISA
50 # then there are 32 bit worth of flags and other data
51 # however, on 64bit systems these are padded to be a full
52 # machine word long, which means we actually have two pointers
53 # worth of data to skip
54 def offset(self):
55 return 2 * self.sys_params.pointer_size
56
57 def length(self):
58 logger = lldb.formatters.Logger.Logger()
59 logger >> "NSConcreteData_SummaryProvider length"
60 size = self.valobj.CreateChildAtOffset(
61 "count", self.offset(), self.sys_params.types_cache.NSUInteger)
62 logger >> str(size)
63 logger >> str(size.GetValueAsUnsigned(0))
64 return size.GetValueAsUnsigned(0)
Enrico Granataeb4a4792012-02-23 23:10:27 +000065
66
67class NSDataUnknown_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000068
Kate Stoneb9c1b512016-09-06 20:57:50 +000069 def adjust_for_architecture(self):
70 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 def __init__(self, valobj, params):
73 logger = lldb.formatters.Logger.Logger()
74 logger >> "NSDataUnknown_SummaryProvider __init__"
75 self.valobj = valobj
76 self.sys_params = params
77 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 def update(self):
80 self.adjust_for_architecture()
81
82 def length(self):
83 logger = lldb.formatters.Logger.Logger()
84 logger >> "NSDataUnknown_SummaryProvider length"
85 stream = lldb.SBStream()
86 self.valobj.GetExpressionPath(stream)
87 logger >> stream.GetData()
88 num_children_vo = self.valobj.CreateValueFromExpression(
89 "count", "(int)[" + stream.GetData() + " length]")
90 logger >> "still in after expression: " + str(num_children_vo)
91 if num_children_vo.IsValid():
92 logger >> "wow - expr output is valid: " + \
93 str(num_children_vo.GetValueAsUnsigned())
94 return num_children_vo.GetValueAsUnsigned(0)
95 logger >> "invalid expr output - too bad"
96 return '<variable is not NSData>'
Enrico Granataeb4a4792012-02-23 23:10:27 +000097
98
99def GetSummary_Impl(valobj):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 global statistics
101 logger = lldb.formatters.Logger.Logger()
102 logger >> "NSData GetSummary_Impl"
103 class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
104 valobj, statistics)
105 if wrapper:
106 logger >> "got a wrapper summary - using it"
107 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 name_string = class_data.class_name()
110 logger >> "class name: " + name_string
111 if name_string == 'NSConcreteData' or \
112 name_string == 'NSConcreteMutableData' or \
113 name_string == '__NSCFData':
114 wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)
115 statistics.metric_hit('code_notrun', valobj)
116 else:
117 wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)
118 statistics.metric_hit(
119 'unknown_class',
120 valobj.GetName() +
121 " seen as " +
122 name_string)
123 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +0000124
Enrico Granata8c69c962012-03-13 00:25:59 +0000125
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126def NSData_SummaryProvider(valobj, dict):
127 logger = lldb.formatters.Logger.Logger()
128 logger >> "NSData_SummaryProvider"
129 provider = GetSummary_Impl(valobj)
130 logger >> "found a summary provider, it is: " + str(provider)
131 if provider is not None:
132 try:
133 summary = provider.length()
134 except:
135 summary = None
136 logger >> "got a summary: it is " + str(summary)
137 if summary is None:
138 summary = '<variable is not NSData>'
139 elif isinstance(summary, basestring):
140 pass
141 else:
142 if summary == 1:
143 summary = '1 byte'
144 else:
145 summary = str(summary) + ' bytes'
146 return summary
147 return 'Summary Unavailable'
148
149
150def NSData_SummaryProvider2(valobj, dict):
151 logger = lldb.formatters.Logger.Logger()
152 logger >> "NSData_SummaryProvider2"
153 provider = GetSummary_Impl(valobj)
154 logger >> "found a summary provider, it is: " + str(provider)
155 if provider is not None:
156 if isinstance(
157 provider,
158 lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
159 return provider.message()
160 try:
161 summary = provider.length()
162 except:
163 summary = None
164 logger >> "got a summary: it is " + str(summary)
165 if summary is None:
166 summary = '<variable is not CFData>'
167 elif isinstance(summary, basestring):
168 pass
169 else:
170 if summary == 1:
171 summary = '@"1 byte"'
172 else:
173 summary = '@"' + str(summary) + ' bytes"'
174 return summary
175 return 'Summary Unavailable'
176
177
178def __lldb_init_module(debugger, dict):
179 debugger.HandleCommand(
180 "type summary add -F NSData.NSData_SummaryProvider NSData")
181 debugger.HandleCommand(
182 "type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef")