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 NSBundle 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 14b370df27c76fd875f3312be487868528121a4838Enrico Granataimport NSURL 150d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.Logger 16b370df27c76fd875f3312be487868528121a4838Enrico Granata 170d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granatastatistics = lldb.formatters.metrics.Metrics() 18b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_isa') 19b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_pointer') 20b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('unknown_class') 21b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('code_notrun') 22b370df27c76fd875f3312be487868528121a4838Enrico Granata 23b370df27c76fd875f3312be487868528121a4838Enrico Granata# despite the similary to synthetic children providers, these classes are not 24b370df27c76fd875f3312be487868528121a4838Enrico Granata# trying to provide anything but a summary for an NSURL, so they need not 25b370df27c76fd875f3312be487868528121a4838Enrico Granata# obey the interface specification for synthetic children providers 26b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSBundleKnown_SummaryProvider: 27b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 28f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 29b370df27c76fd875f3312be487868528121a4838Enrico Granata 30f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 310d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 32b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 33f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 34f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.NSString): 35f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType() 36b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update(); 37b370df27c76fd875f3312be487868528121a4838Enrico Granata 38b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 390d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 40b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 41b370df27c76fd875f3312be487868528121a4838Enrico Granata 42b370df27c76fd875f3312be487868528121a4838Enrico Granata # we need to skip the ISA, plus four other values 43b370df27c76fd875f3312be487868528121a4838Enrico Granata # that are luckily each a pointer in size 44b370df27c76fd875f3312be487868528121a4838Enrico Granata # which makes our computation trivial :-) 45b370df27c76fd875f3312be487868528121a4838Enrico Granata def offset(self): 460d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 47f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 5 * self.sys_params.pointer_size 48b370df27c76fd875f3312be487868528121a4838Enrico Granata 49b370df27c76fd875f3312be487868528121a4838Enrico Granata def url_text(self): 500d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 51b370df27c76fd875f3312be487868528121a4838Enrico Granata global statistics 52b370df27c76fd875f3312be487868528121a4838Enrico Granata text = self.valobj.CreateChildAtOffset("text", 53b370df27c76fd875f3312be487868528121a4838Enrico Granata self.offset(), 54f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSString) 55b370df27c76fd875f3312be487868528121a4838Enrico Granata my_string = text.GetSummary() 56b370df27c76fd875f3312be487868528121a4838Enrico Granata if (my_string == None) or (my_string == ''): 5735eac9d979574950afa087fed398179a92a45c36Enrico Granata statistics.metric_hit('unknown_class',str(self.valobj.GetName()) + " triggered unkown pointer location") 58f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return NSBundleUnknown_SummaryProvider(self.valobj, self.sys_params).url_text() 59b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 60b370df27c76fd875f3312be487868528121a4838Enrico Granata statistics.metric_hit('code_notrun',self.valobj) 61b370df27c76fd875f3312be487868528121a4838Enrico Granata return my_string 62b370df27c76fd875f3312be487868528121a4838Enrico Granata 63b370df27c76fd875f3312be487868528121a4838Enrico Granata 64b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSBundleUnknown_SummaryProvider: 65b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 66f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 67b370df27c76fd875f3312be487868528121a4838Enrico Granata 68f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 690d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 70b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 71f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 72b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 73b370df27c76fd875f3312be487868528121a4838Enrico Granata 74b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 750d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 76b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 77b370df27c76fd875f3312be487868528121a4838Enrico Granata 78b370df27c76fd875f3312be487868528121a4838Enrico Granata def url_text(self): 790d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 80b370df27c76fd875f3312be487868528121a4838Enrico Granata stream = lldb.SBStream() 81b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj.GetExpressionPath(stream) 82b370df27c76fd875f3312be487868528121a4838Enrico Granata expr = "(NSString*)[" + stream.GetData() + " bundlePath]" 83b370df27c76fd875f3312be487868528121a4838Enrico Granata url_text_vo = self.valobj.CreateValueFromExpression("path",expr); 84579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if url_text_vo.IsValid(): 85579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return url_text_vo.GetSummary() 86579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '<variable is not NSBundle>' 87b370df27c76fd875f3312be487868528121a4838Enrico Granata 88b370df27c76fd875f3312be487868528121a4838Enrico Granata 89b370df27c76fd875f3312be487868528121a4838Enrico Granatadef GetSummary_Impl(valobj): 900d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 91b370df27c76fd875f3312be487868528121a4838Enrico Granata global statistics 92a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics) 93579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if wrapper: 94579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 95b370df27c76fd875f3312be487868528121a4838Enrico Granata 96b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string = class_data.class_name() 978f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "class name is: " + str(name_string) 988f18240a09893310c43673901d863892ae7b0611Enrico Granata 99b370df27c76fd875f3312be487868528121a4838Enrico Granata if name_string == 'NSBundle': 100f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params) 101b370df27c76fd875f3312be487868528121a4838Enrico Granata # [NSBundle mainBundle] does return an object that is 102b370df27c76fd875f3312be487868528121a4838Enrico Granata # not correctly filled out for our purposes, so we still 103b370df27c76fd875f3312be487868528121a4838Enrico Granata # end up having to run code in that case 104b370df27c76fd875f3312be487868528121a4838Enrico Granata #statistics.metric_hit('code_notrun',valobj) 105b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 106f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = NSBundleUnknown_SummaryProvider(valobj, class_data.sys_params) 107805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string) 108b370df27c76fd875f3312be487868528121a4838Enrico Granata return wrapper; 109b370df27c76fd875f3312be487868528121a4838Enrico Granata 110b370df27c76fd875f3312be487868528121a4838Enrico Granatadef NSBundle_SummaryProvider (valobj,dict): 1110d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 112b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = GetSummary_Impl(valobj); 113b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider != None: 114a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description): 115579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return provider.message() 116579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata try: 117579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = provider.url_text(); 118579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata except: 119579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = None 1208f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "got summary " + str(summary) 121579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == None or summary == '': 122579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSBundle>' 123579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return summary 124579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 125b370df27c76fd875f3312be487868528121a4838Enrico Granata 126b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict): 127b370df27c76fd875f3312be487868528121a4838Enrico Granata debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle") 128