1""" 2LLDB AppKit formatters 3 4part of The LLVM Compiler Infrastructure 5This file is distributed under the University of Illinois Open Source 6License. See LICENSE.TXT for details. 7""" 8# summary provider for class NSException 9import lldb.runtime.objc.objc_runtime 10import lldb.formatters.metrics 11import CFString 12import lldb 13import lldb.formatters.Logger 14 15statistics = lldb.formatters.metrics.Metrics() 16statistics.add_metric('invalid_isa') 17statistics.add_metric('invalid_pointer') 18statistics.add_metric('unknown_class') 19statistics.add_metric('code_notrun') 20 21class NSKnownException_SummaryProvider: 22 def adjust_for_architecture(self): 23 pass 24 25 def __init__(self, valobj, params): 26 logger = lldb.formatters.Logger.Logger() 27 self.valobj = valobj; 28 self.sys_params = params 29 if not (self.sys_params.types_cache.id): 30 self.sys_params.types_cache.id = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) 31 self.update(); 32 33 def update(self): 34 logger = lldb.formatters.Logger.Logger() 35 self.adjust_for_architecture(); 36 37 def offset_name(self): 38 logger = lldb.formatters.Logger.Logger() 39 return self.sys_params.pointer_size 40 def offset_reason(self): 41 logger = lldb.formatters.Logger.Logger() 42 return 2*self.sys_params.pointer_size 43 44 def description(self): 45 logger = lldb.formatters.Logger.Logger() 46 name_ptr = self.valobj.CreateChildAtOffset("name", 47 self.offset_name(), 48 self.sys_params.types_cache.id) 49 reason_ptr = self.valobj.CreateChildAtOffset("reason", 50 self.offset_reason(), 51 self.sys_params.types_cache.id) 52 return 'name:' + CFString.CFString_SummaryProvider(name_ptr,None) + ' reason:' + CFString.CFString_SummaryProvider(reason_ptr,None) 53 54class NSUnknownException_SummaryProvider: 55 def adjust_for_architecture(self): 56 pass 57 58 def __init__(self, valobj, params): 59 logger = lldb.formatters.Logger.Logger() 60 self.valobj = valobj; 61 self.sys_params = params 62 self.update(); 63 64 def update(self): 65 logger = lldb.formatters.Logger.Logger() 66 self.adjust_for_architecture(); 67 68 def description(self): 69 logger = lldb.formatters.Logger.Logger() 70 stream = lldb.SBStream() 71 self.valobj.GetExpressionPath(stream) 72 name_vo = self.valobj.CreateValueFromExpression("name","(NSString*)[" + stream.GetData() + " name]"); 73 reason_vo = self.valobj.CreateValueFromExpression("reason","(NSString*)[" + stream.GetData() + " reason]"); 74 if name_vo.IsValid() and reason_vo.IsValid(): 75 return CFString.CFString_SummaryProvider(name_vo,None) + ' ' + CFString.CFString_SummaryProvider(reason_vo,None) 76 return '<variable is not NSException>' 77 78 79def GetSummary_Impl(valobj): 80 logger = lldb.formatters.Logger.Logger() 81 global statistics 82 class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics) 83 if wrapper: 84 return wrapper 85 86 name_string = class_data.class_name() 87 logger >> "class name is: " + str(name_string) 88 89 if name_string == 'NSException': 90 wrapper = NSKnownException_SummaryProvider(valobj, class_data.sys_params) 91 statistics.metric_hit('code_notrun',valobj) 92 else: 93 wrapper = NSUnknownException_SummaryProvider(valobj, class_data.sys_params) 94 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string) 95 return wrapper; 96 97def NSException_SummaryProvider (valobj,dict): 98 logger = lldb.formatters.Logger.Logger() 99 provider = GetSummary_Impl(valobj); 100 if provider != None: 101 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description): 102 return provider.message() 103 try: 104 summary = provider.description(); 105 except: 106 summary = None 107 logger >> "got summary " + str(summary) 108 if summary == None: 109 summary = '<variable is not NSException>' 110 return str(summary) 111 return 'Summary Unavailable' 112 113def __lldb_init_module(debugger,dict): 114 debugger.HandleCommand("type summary add -F NSException.NSException_SummaryProvider NSException") 115