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""" 8dc1df6b2fd7d359753b2bcfcf2decb114f465a1dEnrico Granata# example summary provider for CFBinaryHeap 9dc1df6b2fd7d359753b2bcfcf2decb114f465a1dEnrico 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# despite the similary to synthetic children providers, these classes are not 23b370df27c76fd875f3312be487868528121a4838Enrico Granata# trying to provide anything but the length for an CFBinaryHeap, so they need not 24b370df27c76fd875f3312be487868528121a4838Enrico Granata# obey the interface specification for synthetic children providers 25b370df27c76fd875f3312be487868528121a4838Enrico Granataclass CFBinaryHeapRef_SummaryProvider: 26b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 27f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 28b370df27c76fd875f3312be487868528121a4838Enrico Granata 29f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 300d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 31b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 32f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 33f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.NSUInteger): 34f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.sys_params.is_64_bit: 35f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 36f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 37f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 38b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update(); 39b370df27c76fd875f3312be487868528121a4838Enrico Granata 40b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 410d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 42b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 43b370df27c76fd875f3312be487868528121a4838Enrico Granata 44b370df27c76fd875f3312be487868528121a4838Enrico Granata # 8 bytes on i386 45b370df27c76fd875f3312be487868528121a4838Enrico Granata # 16 bytes on x64 46b370df27c76fd875f3312be487868528121a4838Enrico Granata # most probably 2 pointers 47b370df27c76fd875f3312be487868528121a4838Enrico Granata def offset(self): 480d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 49f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 2 * self.sys_params.pointer_size 50b370df27c76fd875f3312be487868528121a4838Enrico Granata 51b370df27c76fd875f3312be487868528121a4838Enrico Granata def length(self): 520d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 53b370df27c76fd875f3312be487868528121a4838Enrico Granata size = self.valobj.CreateChildAtOffset("count", 54b370df27c76fd875f3312be487868528121a4838Enrico Granata self.offset(), 55f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger) 56b370df27c76fd875f3312be487868528121a4838Enrico Granata return size.GetValueAsUnsigned(0) 57b370df27c76fd875f3312be487868528121a4838Enrico Granata 58b370df27c76fd875f3312be487868528121a4838Enrico Granata 59b370df27c76fd875f3312be487868528121a4838Enrico Granataclass CFBinaryHeapUnknown_SummaryProvider: 60b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 61f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 62b370df27c76fd875f3312be487868528121a4838Enrico Granata 63f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 640d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 65b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 66f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 67f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.update(); 68b370df27c76fd875f3312be487868528121a4838Enrico Granata 69b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 700d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 71b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 72b370df27c76fd875f3312be487868528121a4838Enrico Granata 73b370df27c76fd875f3312be487868528121a4838Enrico Granata def length(self): 740d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 75b370df27c76fd875f3312be487868528121a4838Enrico Granata stream = lldb.SBStream() 76b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj.GetExpressionPath(stream) 77b370df27c76fd875f3312be487868528121a4838Enrico Granata num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBinaryHeapGetCount(" + stream.GetData() + " )"); 78579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if num_children_vo.IsValid(): 79579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return num_children_vo.GetValueAsUnsigned(0) 80579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '<variable is not CFBinaryHeap>' 81b370df27c76fd875f3312be487868528121a4838Enrico Granata 82b370df27c76fd875f3312be487868528121a4838Enrico Granata 83b370df27c76fd875f3312be487868528121a4838Enrico Granatadef GetSummary_Impl(valobj): 840d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 85b370df27c76fd875f3312be487868528121a4838Enrico Granata global statistics 86a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics) 87579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if wrapper: 88579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 89b370df27c76fd875f3312be487868528121a4838Enrico Granata 90b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string = class_data.class_name() 91579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata actual_name = class_data.class_name() 928f18240a09893310c43673901d863892ae7b0611Enrico Granata 938f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name) 948f18240a09893310c43673901d863892ae7b0611Enrico Granata 95579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if class_data.is_cftype(): 96b370df27c76fd875f3312be487868528121a4838Enrico Granata # CFBinaryHeap does not expose an actual NSWrapper type, so we have to check that this is 97b370df27c76fd875f3312be487868528121a4838Enrico Granata # an NSCFType and then check we are a pointer-to CFBinaryHeap 98b370df27c76fd875f3312be487868528121a4838Enrico Granata valobj_type = valobj.GetType() 99b370df27c76fd875f3312be487868528121a4838Enrico Granata if valobj_type.IsValid() and valobj_type.IsPointerType(): 100579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata valobj_type = valobj_type.GetPointeeType() 101579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if valobj_type.IsValid(): 102579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata actual_name = valobj_type.GetName() 103579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if actual_name == '__CFBinaryHeap': 104579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = CFBinaryHeapRef_SummaryProvider(valobj, class_data.sys_params) 105579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('code_notrun',valobj) 106579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 107f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = CFBinaryHeapUnknown_SummaryProvider(valobj, class_data.sys_params) 108805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string) 109b370df27c76fd875f3312be487868528121a4838Enrico Granata return wrapper; 110b370df27c76fd875f3312be487868528121a4838Enrico Granata 111b370df27c76fd875f3312be487868528121a4838Enrico Granatadef CFBinaryHeap_SummaryProvider (valobj,dict): 1120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 113b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = GetSummary_Impl(valobj); 114b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider != None: 115a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description): 116579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return provider.message() 117b370df27c76fd875f3312be487868528121a4838Enrico Granata try: 118b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = provider.length(); 119b370df27c76fd875f3312be487868528121a4838Enrico Granata except: 120b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = None 1218f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "summary got from provider: " + str(summary) 122b370df27c76fd875f3312be487868528121a4838Enrico Granata # for some reason, one needs to clear some bits for the count 123b370df27c76fd875f3312be487868528121a4838Enrico Granata # to be correct when using CF(Mutable)BagRef on x64 124b370df27c76fd875f3312be487868528121a4838Enrico Granata # the bit mask was derived through experimentation 125b370df27c76fd875f3312be487868528121a4838Enrico Granata # (if counts start looking weird, then most probably 126b370df27c76fd875f3312be487868528121a4838Enrico Granata # the mask needs to be changed) 127b370df27c76fd875f3312be487868528121a4838Enrico Granata if summary == None: 128579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not CFBinaryHeap>' 129579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata elif isinstance(summary,basestring): 130579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata pass 131b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 132f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if provider.sys_params.is_64_bit: 133b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = summary & ~0x1fff000000000000 134323cec97d94bd1836e8c158e7065fdb5ad71ad48Enrico Granata if summary == 1: 1357b9aacf4a454465af905e505f74245173714b23bEnrico Granata return '@"1 item"' 136323cec97d94bd1836e8c158e7065fdb5ad71ad48Enrico Granata else: 1377b9aacf4a454465af905e505f74245173714b23bEnrico Granata summary = '@"' + str(summary) + ' items"' 138323cec97d94bd1836e8c158e7065fdb5ad71ad48Enrico Granata return summary 139579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 140b370df27c76fd875f3312be487868528121a4838Enrico Granata 141b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict): 142b370df27c76fd875f3312be487868528121a4838Enrico Granata debugger.HandleCommand("type summary add -F CFBinaryHeap.CFBinaryHeap_SummaryProvider CFBinaryHeapRef") 143