1579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 2579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLLDB AppKit formatters 3579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 4579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granatapart of The LLVM Compiler Infrastructure 5579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataThis file is distributed under the University of Illinois Open Source 6579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLicense. See LICENSE.TXT for details. 7579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 8ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata# example summary provider for NSArray 9ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata# the real summary is now C++ code built into LLDB 10b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb 11b370df27c76fd875f3312be487868528121a4838Enrico Granataimport ctypes 120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.runtime.objc.objc_runtime 130d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.metrics 140d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.Logger 15b370df27c76fd875f3312be487868528121a4838Enrico Granata 160d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granatastatistics = lldb.formatters.metrics.Metrics() 17b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_isa') 18b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_pointer') 19b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('unknown_class') 20b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('code_notrun') 21b370df27c76fd875f3312be487868528121a4838Enrico Granata 22b370df27c76fd875f3312be487868528121a4838Enrico Granata# much less functional than the other two cases below 23b370df27c76fd875f3312be487868528121a4838Enrico Granata# just runs code to get to the count and then returns 24b370df27c76fd875f3312be487868528121a4838Enrico Granata# no children 25b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayKVC_SynthProvider: 26b370df27c76fd875f3312be487868528121a4838Enrico Granata 27b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 28f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 29b370df27c76fd875f3312be487868528121a4838Enrico Granata 30f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 310d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 32b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 33b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 34b370df27c76fd875f3312be487868528121a4838Enrico Granata 35b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 360d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 37b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 38b370df27c76fd875f3312be487868528121a4838Enrico Granata 39b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 400d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 41b370df27c76fd875f3312be487868528121a4838Enrico Granata stream = lldb.SBStream() 42b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj.GetExpressionPath(stream) 43b370df27c76fd875f3312be487868528121a4838Enrico Granata num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " count]"); 44579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if num_children_vo.IsValid(): 45579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return num_children_vo.GetValueAsUnsigned(0) 46579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return "<variable is not NSArray>" 47b370df27c76fd875f3312be487868528121a4838Enrico Granata 48b370df27c76fd875f3312be487868528121a4838Enrico Granata# much less functional than the other two cases below 49b370df27c76fd875f3312be487868528121a4838Enrico Granata# just runs code to get to the count and then returns 50b370df27c76fd875f3312be487868528121a4838Enrico Granata# no children 51b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayCF_SynthProvider: 52b370df27c76fd875f3312be487868528121a4838Enrico Granata 53b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 54f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 55b370df27c76fd875f3312be487868528121a4838Enrico Granata 56f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 570d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 58b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 59f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 60f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not (self.sys_params.types_cache.ulong): 61f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 62b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 63b370df27c76fd875f3312be487868528121a4838Enrico Granata 64b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 650d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 66b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 67b370df27c76fd875f3312be487868528121a4838Enrico Granata 68b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 690d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 70b370df27c76fd875f3312be487868528121a4838Enrico Granata num_children_vo = self.valobj.CreateChildAtOffset("count", 71f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.cfruntime_size, 72f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.ulong) 73b370df27c76fd875f3312be487868528121a4838Enrico Granata return num_children_vo.GetValueAsUnsigned(0) 74b370df27c76fd875f3312be487868528121a4838Enrico Granata 75b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayI_SynthProvider: 76b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 77f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 78b370df27c76fd875f3312be487868528121a4838Enrico Granata 79f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 800d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 81b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 82f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 83f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.long): 84f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) 85b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 86b370df27c76fd875f3312be487868528121a4838Enrico Granata 87b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 880d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 89b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 90b370df27c76fd875f3312be487868528121a4838Enrico Granata 91b370df27c76fd875f3312be487868528121a4838Enrico Granata # skip the isa pointer and get at the size 92b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 930d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 94b370df27c76fd875f3312be487868528121a4838Enrico Granata count = self.valobj.CreateChildAtOffset("count", 95f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.pointer_size, 96f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long); 97f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return count.GetValueAsUnsigned(0) 98b370df27c76fd875f3312be487868528121a4838Enrico Granata 99b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayM_SynthProvider: 100b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 101f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 102b370df27c76fd875f3312be487868528121a4838Enrico Granata 103f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 1040d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 105b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 106f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 107f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.long): 108f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) 109f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.update() 110b370df27c76fd875f3312be487868528121a4838Enrico Granata 111b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 1120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 113b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 114b370df27c76fd875f3312be487868528121a4838Enrico Granata 115b370df27c76fd875f3312be487868528121a4838Enrico Granata # skip the isa pointer and get at the size 116b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 1170d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 118b370df27c76fd875f3312be487868528121a4838Enrico Granata count = self.valobj.CreateChildAtOffset("count", 119f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.pointer_size, 120f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long); 121f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return count.GetValueAsUnsigned(0) 122b370df27c76fd875f3312be487868528121a4838Enrico Granata 123b370df27c76fd875f3312be487868528121a4838Enrico Granata# this is the actual synth provider, but is just a wrapper that checks 124b370df27c76fd875f3312be487868528121a4838Enrico Granata# whether valobj is an instance of __NSArrayI or __NSArrayM and sets up an 125b370df27c76fd875f3312be487868528121a4838Enrico Granata# appropriate backend layer to do the computations 126b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArray_SynthProvider: 127b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 128f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 129b370df27c76fd875f3312be487868528121a4838Enrico Granata 130b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self, valobj, dict): 1310d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 132b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 133b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture() 134579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.error = False 135579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.wrapper = self.make_wrapper() 136b370df27c76fd875f3312be487868528121a4838Enrico Granata self.invalid = (self.wrapper == None) 137b370df27c76fd875f3312be487868528121a4838Enrico Granata 138b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 1390d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 140b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.wrapper == None: 141b370df27c76fd875f3312be487868528121a4838Enrico Granata return 0; 142b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.wrapper.num_children() 143b370df27c76fd875f3312be487868528121a4838Enrico Granata 144b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 1450d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 146b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.wrapper == None: 147f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 148f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.wrapper.update() 149b370df27c76fd875f3312be487868528121a4838Enrico Granata 150b370df27c76fd875f3312be487868528121a4838Enrico Granata # this code acts as our defense against NULL and unitialized 151b370df27c76fd875f3312be487868528121a4838Enrico Granata # NSArray pointers, which makes it much longer than it would be otherwise 152579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def make_wrapper(self): 1530d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 154579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if self.valobj.GetValueAsUnsigned() == 0: 155579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.error = True 1560ff10b595416cc33bd66ecbdbcb93935327be0d0Enrico Granata return lldb.runtime.objc.objc_runtime.InvalidPointer_Description(True) 157579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 158579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata global statistics 159a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(self.valobj,statistics) 160579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if wrapper: 161579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.error = True 162579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 163b370df27c76fd875f3312be487868528121a4838Enrico Granata 164b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string = class_data.class_name() 1658f18240a09893310c43673901d863892ae7b0611Enrico Granata 1668f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Class name is " + str(name_string) 1678f18240a09893310c43673901d863892ae7b0611Enrico Granata 168b370df27c76fd875f3312be487868528121a4838Enrico Granata if name_string == '__NSArrayI': 169579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayI_SynthProvider(self.valobj, dict, class_data.sys_params) 1706805e3f988769b01a1c9bcdba1497afb026a8058Enrico Granata statistics.metric_hit('code_notrun',self.valobj.GetName()) 171b370df27c76fd875f3312be487868528121a4838Enrico Granata elif name_string == '__NSArrayM': 172579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayM_SynthProvider(self.valobj, dict, class_data.sys_params) 1736805e3f988769b01a1c9bcdba1497afb026a8058Enrico Granata statistics.metric_hit('code_notrun',self.valobj.GetName()) 174b370df27c76fd875f3312be487868528121a4838Enrico Granata elif name_string == '__NSCFArray': 175579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayCF_SynthProvider(self.valobj, dict, class_data.sys_params) 1766805e3f988769b01a1c9bcdba1497afb026a8058Enrico Granata statistics.metric_hit('code_notrun',self.valobj.GetName()) 177b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 178579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayKVC_SynthProvider(self.valobj, dict, class_data.sys_params) 1796805e3f988769b01a1c9bcdba1497afb026a8058Enrico Granata statistics.metric_hit('unknown_class',str(self.valobj.GetName()) + " seen as " + name_string) 180b370df27c76fd875f3312be487868528121a4838Enrico Granata return wrapper; 181b370df27c76fd875f3312be487868528121a4838Enrico Granata 182b370df27c76fd875f3312be487868528121a4838Enrico Granatadef CFArray_SummaryProvider (valobj,dict): 1830d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 184b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = NSArray_SynthProvider(valobj,dict); 185b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider.invalid == False: 186579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if provider.error == True: 187579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return provider.wrapper.message() 188579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata try: 189579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = int(provider.num_children()); 190579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata except: 191579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = None 1928f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "provider gave me " + str(summary) 193579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == None: 194579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSArray>' 195579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata elif isinstance(summary,basestring): 196579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata pass 197579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 198579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata # we format it like it were a CFString to make it look the same as the summary from Xcode 199579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '@"' + str(summary) + (" objects" if summary != 1 else " object") + '"' 200579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return summary 201579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 202b370df27c76fd875f3312be487868528121a4838Enrico Granata 203b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict): 204b370df27c76fd875f3312be487868528121a4838Enrico Granata debugger.HandleCommand("type summary add -F CFArray.CFArray_SummaryProvider NSArray CFArrayRef CFMutableArrayRef") 205