CFBinaryHeap.py revision f2a84671ff78bee1f82b60698f3ee9791585f8ac
1b370df27c76fd875f3312be487868528121a4838Enrico Granata# summary provider for CFBinaryHeap 2b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb 3b370df27c76fd875f3312be487868528121a4838Enrico Granataimport ctypes 4b370df27c76fd875f3312be487868528121a4838Enrico Granataimport objc_runtime 5b370df27c76fd875f3312be487868528121a4838Enrico Granataimport metrics 6b370df27c76fd875f3312be487868528121a4838Enrico Granata 7b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics = metrics.Metrics() 8b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_isa') 9b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_pointer') 10b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('unknown_class') 11b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('code_notrun') 12b370df27c76fd875f3312be487868528121a4838Enrico Granata 13b370df27c76fd875f3312be487868528121a4838Enrico Granata# despite the similary to synthetic children providers, these classes are not 14b370df27c76fd875f3312be487868528121a4838Enrico Granata# trying to provide anything but the length for an CFBinaryHeap, so they need not 15b370df27c76fd875f3312be487868528121a4838Enrico Granata# obey the interface specification for synthetic children providers 16b370df27c76fd875f3312be487868528121a4838Enrico Granataclass CFBinaryHeapRef_SummaryProvider: 17b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 18f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 19b370df27c76fd875f3312be487868528121a4838Enrico Granata 20f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 21b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 22f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 23f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.NSUInteger): 24f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.sys_params.is_64_bit: 25f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 26f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 27f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 28b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update(); 29b370df27c76fd875f3312be487868528121a4838Enrico Granata 30b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 31b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 32b370df27c76fd875f3312be487868528121a4838Enrico Granata 33b370df27c76fd875f3312be487868528121a4838Enrico Granata # 8 bytes on i386 34b370df27c76fd875f3312be487868528121a4838Enrico Granata # 16 bytes on x64 35b370df27c76fd875f3312be487868528121a4838Enrico Granata # most probably 2 pointers 36b370df27c76fd875f3312be487868528121a4838Enrico Granata def offset(self): 37f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 2 * self.sys_params.pointer_size 38b370df27c76fd875f3312be487868528121a4838Enrico Granata 39b370df27c76fd875f3312be487868528121a4838Enrico Granata def length(self): 40b370df27c76fd875f3312be487868528121a4838Enrico Granata size = self.valobj.CreateChildAtOffset("count", 41b370df27c76fd875f3312be487868528121a4838Enrico Granata self.offset(), 42f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger) 43b370df27c76fd875f3312be487868528121a4838Enrico Granata return size.GetValueAsUnsigned(0) 44b370df27c76fd875f3312be487868528121a4838Enrico Granata 45b370df27c76fd875f3312be487868528121a4838Enrico Granata 46b370df27c76fd875f3312be487868528121a4838Enrico Granataclass CFBinaryHeapUnknown_SummaryProvider: 47b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 48f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 49b370df27c76fd875f3312be487868528121a4838Enrico Granata 50f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 51b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 52f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 53f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.update(); 54b370df27c76fd875f3312be487868528121a4838Enrico Granata 55b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 56b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 57b370df27c76fd875f3312be487868528121a4838Enrico Granata 58b370df27c76fd875f3312be487868528121a4838Enrico Granata def length(self): 59b370df27c76fd875f3312be487868528121a4838Enrico Granata stream = lldb.SBStream() 60b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj.GetExpressionPath(stream) 61b370df27c76fd875f3312be487868528121a4838Enrico Granata num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBinaryHeapGetCount(" + stream.GetData() + " )"); 62b370df27c76fd875f3312be487868528121a4838Enrico Granata return num_children_vo.GetValueAsUnsigned(0) 63b370df27c76fd875f3312be487868528121a4838Enrico Granata 64b370df27c76fd875f3312be487868528121a4838Enrico Granata 65b370df27c76fd875f3312be487868528121a4838Enrico Granatadef GetSummary_Impl(valobj): 66b370df27c76fd875f3312be487868528121a4838Enrico Granata global statistics 67b370df27c76fd875f3312be487868528121a4838Enrico Granata class_data = objc_runtime.ObjCRuntime(valobj) 68b370df27c76fd875f3312be487868528121a4838Enrico Granata if class_data.is_valid() == False: 69b370df27c76fd875f3312be487868528121a4838Enrico Granata statistics.metric_hit('invalid_pointer',valobj) 70b370df27c76fd875f3312be487868528121a4838Enrico Granata wrapper = None 71b370df27c76fd875f3312be487868528121a4838Enrico Granata return 72b370df27c76fd875f3312be487868528121a4838Enrico Granata class_data = class_data.read_class_data() 73b370df27c76fd875f3312be487868528121a4838Enrico Granata if class_data.is_valid() == False: 74b370df27c76fd875f3312be487868528121a4838Enrico Granata statistics.metric_hit('invalid_isa',valobj) 75b370df27c76fd875f3312be487868528121a4838Enrico Granata wrapper = None 76b370df27c76fd875f3312be487868528121a4838Enrico Granata return 77b370df27c76fd875f3312be487868528121a4838Enrico Granata if class_data.is_kvo(): 78b370df27c76fd875f3312be487868528121a4838Enrico Granata class_data = class_data.get_superclass() 79b370df27c76fd875f3312be487868528121a4838Enrico Granata if class_data.is_valid() == False: 80b370df27c76fd875f3312be487868528121a4838Enrico Granata statistics.metric_hit('invalid_isa',valobj) 81b370df27c76fd875f3312be487868528121a4838Enrico Granata wrapper = None 82b370df27c76fd875f3312be487868528121a4838Enrico Granata return 83b370df27c76fd875f3312be487868528121a4838Enrico Granata 84b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string = class_data.class_name() 85b370df27c76fd875f3312be487868528121a4838Enrico Granata if name_string == '__NSCFType': 86b370df27c76fd875f3312be487868528121a4838Enrico Granata # CFBinaryHeap does not expose an actual NSWrapper type, so we have to check that this is 87b370df27c76fd875f3312be487868528121a4838Enrico Granata # an NSCFType and then check we are a pointer-to CFBinaryHeap 88b370df27c76fd875f3312be487868528121a4838Enrico Granata valobj_type = valobj.GetType() 89b370df27c76fd875f3312be487868528121a4838Enrico Granata if valobj_type.IsValid() and valobj_type.IsPointerType(): 90b370df27c76fd875f3312be487868528121a4838Enrico Granata pointee_type = valobj_type.GetPointeeType() 91b370df27c76fd875f3312be487868528121a4838Enrico Granata if pointee_type.GetName() == '__CFBinaryHeap': 92f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = CFBinaryHeapRef_SummaryProvider(valobj, class_data.sys_params) 93b370df27c76fd875f3312be487868528121a4838Enrico Granata statistics.metric_hit('code_notrun',valobj) 94b370df27c76fd875f3312be487868528121a4838Enrico Granata return wrapper 95f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = CFBinaryHeapUnknown_SummaryProvider(valobj, class_data.sys_params) 96b370df27c76fd875f3312be487868528121a4838Enrico Granata statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) 97b370df27c76fd875f3312be487868528121a4838Enrico Granata return wrapper; 98b370df27c76fd875f3312be487868528121a4838Enrico Granata 99b370df27c76fd875f3312be487868528121a4838Enrico Granatadef CFBinaryHeap_SummaryProvider (valobj,dict): 100b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = GetSummary_Impl(valobj); 101b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider != None: 102b370df27c76fd875f3312be487868528121a4838Enrico Granata try: 103b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = provider.length(); 104b370df27c76fd875f3312be487868528121a4838Enrico Granata except: 105b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = None 106b370df27c76fd875f3312be487868528121a4838Enrico Granata # for some reason, one needs to clear some bits for the count 107b370df27c76fd875f3312be487868528121a4838Enrico Granata # to be correct when using CF(Mutable)BagRef on x64 108b370df27c76fd875f3312be487868528121a4838Enrico Granata # the bit mask was derived through experimentation 109b370df27c76fd875f3312be487868528121a4838Enrico Granata # (if counts start looking weird, then most probably 110b370df27c76fd875f3312be487868528121a4838Enrico Granata # the mask needs to be changed) 111b370df27c76fd875f3312be487868528121a4838Enrico Granata if summary == None: 112b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = 'no valid set here' 113b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 114f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if provider.sys_params.is_64_bit: 115b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = summary & ~0x1fff000000000000 116b370df27c76fd875f3312be487868528121a4838Enrico Granata if summary == 1: 117b370df27c76fd875f3312be487868528121a4838Enrico Granata return '1 item' 118b370df27c76fd875f3312be487868528121a4838Enrico Granata return str(summary) + " items" 119b370df27c76fd875f3312be487868528121a4838Enrico Granata return '' 120b370df27c76fd875f3312be487868528121a4838Enrico Granata 121b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict): 122b370df27c76fd875f3312be487868528121a4838Enrico Granata debugger.HandleCommand("type summary add -F CFBinaryHeap.CFBinaryHeap_SummaryProvider CFBinaryHeapRef") 123