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