blob: 3aa30b29f54bab31b5f892de0edb82dd153e4a2f [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
25class NSConcreteData_SummaryProvider:
26 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000027 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000028
Enrico Granatacfdafa32012-03-05 19:56:33 +000029 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000030 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000031 logger >> "NSConcreteData_SummaryProvider __init__"
Enrico Granataeb4a4792012-02-23 23:10:27 +000032 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000033 self.sys_params = params
34 if not(self.sys_params.types_cache.NSUInteger):
35 if self.sys_params.is_64_bit:
36 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
37 else:
38 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
Enrico Granataeb4a4792012-02-23 23:10:27 +000039 self.update();
40
41 def update(self):
42 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000043
44 # one pointer is the ISA
45 # then there are 32 bit worth of flags and other data
46 # however, on 64bit systems these are padded to be a full
47 # machine word long, which means we actually have two pointers
48 # worth of data to skip
49 def offset(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000050 return 2 * self.sys_params.pointer_size
Enrico Granataeb4a4792012-02-23 23:10:27 +000051
52 def length(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000053 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000054 logger >> "NSConcreteData_SummaryProvider length"
Enrico Granataeb4a4792012-02-23 23:10:27 +000055 size = self.valobj.CreateChildAtOffset("count",
56 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +000057 self.sys_params.types_cache.NSUInteger)
Enrico Granatad50f18b2012-03-29 19:29:45 +000058 logger >> str(size)
59 logger >> str(size.GetValueAsUnsigned(0))
Enrico Granataeb4a4792012-02-23 23:10:27 +000060 return size.GetValueAsUnsigned(0)
61
62
63class NSDataUnknown_SummaryProvider:
64 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000065 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000066
Enrico Granatacfdafa32012-03-05 19:56:33 +000067 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000068 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000069 logger >> "NSDataUnknown_SummaryProvider __init__"
Enrico Granataeb4a4792012-02-23 23:10:27 +000070 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000071 self.sys_params = params
72 self.update();
Enrico Granataeb4a4792012-02-23 23:10:27 +000073
74 def update(self):
75 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000076
77 def length(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000078 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000079 logger >> "NSDataUnknown_SummaryProvider length"
Enrico Granataeb4a4792012-02-23 23:10:27 +000080 stream = lldb.SBStream()
81 self.valobj.GetExpressionPath(stream)
Enrico Granatad50f18b2012-03-29 19:29:45 +000082 logger >> stream.GetData()
Enrico Granataeb4a4792012-02-23 23:10:27 +000083 num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " length]");
Enrico Granatad50f18b2012-03-29 19:29:45 +000084 logger >> "still in after expression: " + str(num_children_vo)
Enrico Granata3f1052b2012-03-13 21:52:00 +000085 if num_children_vo.IsValid():
Enrico Granatad50f18b2012-03-29 19:29:45 +000086 logger >> "wow - expr output is valid: " + str(num_children_vo.GetValueAsUnsigned())
Enrico Granata3f1052b2012-03-13 21:52:00 +000087 return num_children_vo.GetValueAsUnsigned(0)
Enrico Granatad50f18b2012-03-29 19:29:45 +000088 logger >> "invalid expr output - too bad"
Enrico Granata3f1052b2012-03-13 21:52:00 +000089 return '<variable is not NSData>'
Enrico Granataeb4a4792012-02-23 23:10:27 +000090
91
92def GetSummary_Impl(valobj):
93 global statistics
Enrico Granata28399ad2012-04-25 01:39:27 +000094 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000095 logger >> "NSData GetSummary_Impl"
Enrico Granata7d222212012-04-25 17:53:41 +000096 class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
Enrico Granata3f1052b2012-03-13 21:52:00 +000097 if wrapper:
Enrico Granatad50f18b2012-03-29 19:29:45 +000098 logger >> "got a wrapper summary - using it"
Enrico Granata3f1052b2012-03-13 21:52:00 +000099 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +0000100
101 name_string = class_data.class_name()
Enrico Granatad50f18b2012-03-29 19:29:45 +0000102 logger >> "class name: " + name_string
Enrico Granataeb4a4792012-02-23 23:10:27 +0000103 if name_string == 'NSConcreteData' or \
104 name_string == 'NSConcreteMutableData' or \
105 name_string == '__NSCFData':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000106 wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000107 statistics.metric_hit('code_notrun',valobj)
108 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000109 wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataa7daeeb2012-03-30 00:51:12 +0000110 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000111 return wrapper;
112
113def NSData_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000114 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +0000115 logger >> "NSData_SummaryProvider"
Enrico Granataeb4a4792012-02-23 23:10:27 +0000116 provider = GetSummary_Impl(valobj);
Enrico Granatad50f18b2012-03-29 19:29:45 +0000117 logger >> "found a summary provider, it is: " + str(provider)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000118 if provider != None:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000119 try:
120 summary = provider.length();
121 except:
122 summary = None
Enrico Granatad50f18b2012-03-29 19:29:45 +0000123 logger >> "got a summary: it is " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000124 if summary == None:
125 summary = '<variable is not NSData>'
126 elif isinstance(summary,basestring):
127 pass
128 else:
129 if summary == 1:
130 summary = '1 byte'
131 else:
132 summary = str(summary) + ' bytes'
133 return summary
134 return 'Summary Unavailable'
Enrico Granataeb4a4792012-02-23 23:10:27 +0000135
Enrico Granata8c69c962012-03-13 00:25:59 +0000136def NSData_SummaryProvider2 (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000137 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +0000138 logger >> "NSData_SummaryProvider2"
Enrico Granata8c69c962012-03-13 00:25:59 +0000139 provider = GetSummary_Impl(valobj);
Enrico Granatad50f18b2012-03-29 19:29:45 +0000140 logger >> "found a summary provider, it is: " + str(provider)
Enrico Granata8c69c962012-03-13 00:25:59 +0000141 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000142 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000143 return provider.message()
144 try:
145 summary = provider.length();
146 except:
147 summary = None
Enrico Granatad50f18b2012-03-29 19:29:45 +0000148 logger >> "got a summary: it is " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000149 if summary == None:
150 summary = '<variable is not CFData>'
151 elif isinstance(summary,basestring):
152 pass
153 else:
154 if summary == 1:
155 summary = '@"1 byte"'
156 else:
157 summary = '@"' + str(summary) + ' bytes"'
158 return summary
159 return 'Summary Unavailable'
Enrico Granata8c69c962012-03-13 00:25:59 +0000160
Enrico Granataeb4a4792012-02-23 23:10:27 +0000161def __lldb_init_module(debugger,dict):
Enrico Granata8c69c962012-03-13 00:25:59 +0000162 debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData")
163 debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef")