diff options
Diffstat (limited to 'lldb/examples/summaries/cocoa/NSBundle.py')
-rw-r--r-- | lldb/examples/summaries/cocoa/NSBundle.py | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/lldb/examples/summaries/cocoa/NSBundle.py b/lldb/examples/summaries/cocoa/NSBundle.py new file mode 100644 index 00000000000..5e6b11a6fc0 --- /dev/null +++ b/lldb/examples/summaries/cocoa/NSBundle.py @@ -0,0 +1,125 @@ +# summary provider for NSBundle +import lldb +import ctypes +import objc_runtime +import metrics +import NSURL + +statistics = metrics.Metrics() +statistics.add_metric('invalid_isa') +statistics.add_metric('invalid_pointer') +statistics.add_metric('unknown_class') +statistics.add_metric('code_notrun') + +# despite the similary to synthetic children providers, these classes are not +# trying to provide anything but a summary for an NSURL, so they need not +# obey the interface specification for synthetic children providers +class NSBundleKnown_SummaryProvider: + def adjust_for_architecture(self): + self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) + self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) + self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + + def __init__(self, valobj): + self.valobj = valobj; + self.update(); + + def update(self): + self.adjust_for_architecture(); + self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) + if self.lp64: + self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + self.pointer_size = 8 + else: + self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) + self.pointer_size = 4 + self.NSString = self.valobj.GetTarget().FindFirstType('NSString') + self.NSURL = self.valobj.GetTarget().FindFirstType('NSURL') + + # we need to skip the ISA, plus four other values + # that are luckily each a pointer in size + # which makes our computation trivial :-) + def offset(self): + return 5 * self.pointer_size + + def url_text(self): + global statistics + text = self.valobj.CreateChildAtOffset("text", + self.offset(), + self.NSString.GetPointerType()) + my_string = text.GetSummary() + if (my_string == None) or (my_string == ''): + statistics.metric_hit('unknown_class',str(self.valobj) + " triggered unkown pointer location") + return NSBundleUnknown_SummaryProvider(self.valobj).url_text() + else: + statistics.metric_hit('code_notrun',self.valobj) + return my_string + + +class NSBundleUnknown_SummaryProvider: + def adjust_for_architecture(self): + self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) + self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) + self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + + def __init__(self, valobj): + self.valobj = valobj; + self.update() + + def update(self): + self.adjust_for_architecture(); + self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) + + def url_text(self): + stream = lldb.SBStream() + self.valobj.GetExpressionPath(stream) + expr = "(NSString*)[" + stream.GetData() + " bundlePath]" + url_text_vo = self.valobj.CreateValueFromExpression("path",expr); + return url_text_vo.GetSummary() + + +def GetSummary_Impl(valobj): + global statistics + class_data = objc_runtime.ObjCRuntime(valobj) + if class_data.is_valid() == False: + statistics.metric_hit('invalid_pointer',valobj) + wrapper = None + return + class_data = class_data.read_class_data() + if class_data.is_valid() == False: + statistics.metric_hit('invalid_isa',valobj) + wrapper = None + return + if class_data.is_kvo(): + class_data = class_data.get_superclass() + if class_data.is_valid() == False: + statistics.metric_hit('invalid_isa',valobj) + wrapper = None + return + + name_string = class_data.class_name() + if name_string == 'NSBundle': + wrapper = NSBundleKnown_SummaryProvider(valobj) + # [NSBundle mainBundle] does return an object that is + # not correctly filled out for our purposes, so we still + # end up having to run code in that case + #statistics.metric_hit('code_notrun',valobj) + else: + wrapper = NSBundleUnknown_SummaryProvider(valobj) + statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) + return wrapper; + +def NSBundle_SummaryProvider (valobj,dict): + provider = GetSummary_Impl(valobj); + if provider != None: + try: + summary = provider.url_text(); + except: + summary = None + if summary == None or summary == '': + summary = 'no valid NSBundle here' + return summary + return '' + +def __lldb_init_module(debugger,dict): + debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle") |