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