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 NSData 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# despite the similary to synthetic children providers, these classes are not 23b370df27c76fd875f3312be487868528121a4838Enrico Granata# trying to provide anything but the length for an NSData, so they need not 24b370df27c76fd875f3312be487868528121a4838Enrico Granata# obey the interface specification for synthetic children providers 25b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSConcreteData_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() 317e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "NSConcreteData_SummaryProvider __init__" 32b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 33f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 34f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.NSUInteger): 35f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.sys_params.is_64_bit: 36f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 37f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 38f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 39b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update(); 40b370df27c76fd875f3312be487868528121a4838Enrico Granata 41b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 42b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 43b370df27c76fd875f3312be487868528121a4838Enrico Granata 44b370df27c76fd875f3312be487868528121a4838Enrico Granata # one pointer is the ISA 45b370df27c76fd875f3312be487868528121a4838Enrico Granata # then there are 32 bit worth of flags and other data 46b370df27c76fd875f3312be487868528121a4838Enrico Granata # however, on 64bit systems these are padded to be a full 47b370df27c76fd875f3312be487868528121a4838Enrico Granata # machine word long, which means we actually have two pointers 48b370df27c76fd875f3312be487868528121a4838Enrico Granata # worth of data to skip 49b370df27c76fd875f3312be487868528121a4838Enrico Granata def offset(self): 50f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 2 * self.sys_params.pointer_size 51b370df27c76fd875f3312be487868528121a4838Enrico Granata 52b370df27c76fd875f3312be487868528121a4838Enrico Granata def length(self): 530d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 547e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "NSConcreteData_SummaryProvider length" 55b370df27c76fd875f3312be487868528121a4838Enrico Granata size = self.valobj.CreateChildAtOffset("count", 56b370df27c76fd875f3312be487868528121a4838Enrico Granata self.offset(), 57f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger) 587e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> str(size) 597e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> str(size.GetValueAsUnsigned(0)) 60b370df27c76fd875f3312be487868528121a4838Enrico Granata return size.GetValueAsUnsigned(0) 61b370df27c76fd875f3312be487868528121a4838Enrico Granata 62b370df27c76fd875f3312be487868528121a4838Enrico Granata 63b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSDataUnknown_SummaryProvider: 64b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 65f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 66b370df27c76fd875f3312be487868528121a4838Enrico Granata 67f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 680d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 697e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "NSDataUnknown_SummaryProvider __init__" 70b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 71f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 72f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.update(); 73b370df27c76fd875f3312be487868528121a4838Enrico Granata 74b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 75b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 76b370df27c76fd875f3312be487868528121a4838Enrico Granata 77b370df27c76fd875f3312be487868528121a4838Enrico Granata def length(self): 780d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 797e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "NSDataUnknown_SummaryProvider length" 80b370df27c76fd875f3312be487868528121a4838Enrico Granata stream = lldb.SBStream() 81b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj.GetExpressionPath(stream) 827e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> stream.GetData() 83b370df27c76fd875f3312be487868528121a4838Enrico Granata num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " length]"); 847e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "still in after expression: " + str(num_children_vo) 85579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if num_children_vo.IsValid(): 867e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "wow - expr output is valid: " + str(num_children_vo.GetValueAsUnsigned()) 87579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return num_children_vo.GetValueAsUnsigned(0) 887e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "invalid expr output - too bad" 89579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '<variable is not NSData>' 90b370df27c76fd875f3312be487868528121a4838Enrico Granata 91b370df27c76fd875f3312be487868528121a4838Enrico Granata 92b370df27c76fd875f3312be487868528121a4838Enrico Granatadef GetSummary_Impl(valobj): 93b370df27c76fd875f3312be487868528121a4838Enrico Granata global statistics 940d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 957e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "NSData GetSummary_Impl" 96a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics) 97579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if wrapper: 987e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "got a wrapper summary - using it" 99579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 100b370df27c76fd875f3312be487868528121a4838Enrico Granata 101b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string = class_data.class_name() 1027e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "class name: " + name_string 103b370df27c76fd875f3312be487868528121a4838Enrico Granata if name_string == 'NSConcreteData' or \ 104b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string == 'NSConcreteMutableData' or \ 105b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string == '__NSCFData': 106f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params) 107b370df27c76fd875f3312be487868528121a4838Enrico Granata statistics.metric_hit('code_notrun',valobj) 108b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 109f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params) 110805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string) 111b370df27c76fd875f3312be487868528121a4838Enrico Granata return wrapper; 112b370df27c76fd875f3312be487868528121a4838Enrico Granata 113b370df27c76fd875f3312be487868528121a4838Enrico Granatadef NSData_SummaryProvider (valobj,dict): 1140d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 1157e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "NSData_SummaryProvider" 116b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = GetSummary_Impl(valobj); 1177e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "found a summary provider, it is: " + str(provider) 118b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider != None: 119579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata try: 120579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = provider.length(); 121579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata except: 122579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = None 1237e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "got a summary: it is " + str(summary) 124579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == None: 125579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSData>' 126579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata elif isinstance(summary,basestring): 127579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata pass 128579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 129579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == 1: 130579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '1 byte' 131579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 132579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = str(summary) + ' bytes' 133579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return summary 134579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 135b370df27c76fd875f3312be487868528121a4838Enrico Granata 1367b9aacf4a454465af905e505f74245173714b23bEnrico Granatadef NSData_SummaryProvider2 (valobj,dict): 1370d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 1387e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "NSData_SummaryProvider2" 1397b9aacf4a454465af905e505f74245173714b23bEnrico Granata provider = GetSummary_Impl(valobj); 1407e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "found a summary provider, it is: " + str(provider) 1417b9aacf4a454465af905e505f74245173714b23bEnrico Granata if provider != None: 142a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description): 143579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return provider.message() 144579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata try: 145579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = provider.length(); 146579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata except: 147579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = None 1487e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata logger >> "got a summary: it is " + str(summary) 149579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == None: 150579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not CFData>' 151579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata elif isinstance(summary,basestring): 152579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata pass 153579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 154579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == 1: 155579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '@"1 byte"' 156579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 157579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '@"' + str(summary) + ' bytes"' 158579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return summary 159579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 1607b9aacf4a454465af905e505f74245173714b23bEnrico Granata 161b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict): 1627b9aacf4a454465af905e505f74245173714b23bEnrico Granata debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData") 1637b9aacf4a454465af905e505f74245173714b23bEnrico Granata debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef") 164