1""" 2LLDB AppKit formatters 3 4Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5See https://llvm.org/LICENSE.txt for license information. 6SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 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 21 22class NSKnownException_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( 32 lldb.eBasicTypeObjCID 33 ) 34 self.update() 35 36 def update(self): 37 logger = lldb.formatters.Logger.Logger() 38 self.adjust_for_architecture() 39 40 def offset_name(self): 41 logger = lldb.formatters.Logger.Logger() 42 return self.sys_params.pointer_size 43 44 def offset_reason(self): 45 logger = lldb.formatters.Logger.Logger() 46 return 2 * self.sys_params.pointer_size 47 48 def description(self): 49 logger = lldb.formatters.Logger.Logger() 50 name_ptr = self.valobj.CreateChildAtOffset( 51 "name", self.offset_name(), self.sys_params.types_cache.id 52 ) 53 reason_ptr = self.valobj.CreateChildAtOffset( 54 "reason", self.offset_reason(), self.sys_params.types_cache.id 55 ) 56 return ( 57 "name:" 58 + CFString.CFString_SummaryProvider(name_ptr, None) 59 + " reason:" 60 + CFString.CFString_SummaryProvider(reason_ptr, None) 61 ) 62 63 64class NSUnknownException_SummaryProvider: 65 def adjust_for_architecture(self): 66 pass 67 68 def __init__(self, valobj, params): 69 logger = lldb.formatters.Logger.Logger() 70 self.valobj = valobj 71 self.sys_params = params 72 self.update() 73 74 def update(self): 75 logger = lldb.formatters.Logger.Logger() 76 self.adjust_for_architecture() 77 78 def description(self): 79 logger = lldb.formatters.Logger.Logger() 80 stream = lldb.SBStream() 81 self.valobj.GetExpressionPath(stream) 82 name_vo = self.valobj.CreateValueFromExpression( 83 "name", "(NSString*)[" + stream.GetData() + " name]" 84 ) 85 reason_vo = self.valobj.CreateValueFromExpression( 86 "reason", "(NSString*)[" + stream.GetData() + " reason]" 87 ) 88 if name_vo.IsValid() and reason_vo.IsValid(): 89 return ( 90 CFString.CFString_SummaryProvider(name_vo, None) 91 + " " 92 + CFString.CFString_SummaryProvider(reason_vo, None) 93 ) 94 return "<variable is not NSException>" 95 96 97def GetSummary_Impl(valobj): 98 logger = lldb.formatters.Logger.Logger() 99 global statistics 100 ( 101 class_data, 102 wrapper, 103 ) = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection( 104 valobj, statistics 105 ) 106 if wrapper: 107 return wrapper 108 109 name_string = class_data.class_name() 110 logger >> "class name is: " + str(name_string) 111 112 if name_string == "NSException": 113 wrapper = NSKnownException_SummaryProvider(valobj, class_data.sys_params) 114 statistics.metric_hit("code_notrun", valobj) 115 else: 116 wrapper = NSUnknownException_SummaryProvider(valobj, class_data.sys_params) 117 statistics.metric_hit( 118 "unknown_class", valobj.GetName() + " seen as " + name_string 119 ) 120 return wrapper 121 122 123def NSException_SummaryProvider(valobj, dict): 124 logger = lldb.formatters.Logger.Logger() 125 provider = GetSummary_Impl(valobj) 126 if provider is not None: 127 if isinstance( 128 provider, lldb.runtime.objc.objc_runtime.SpecialSituation_Description 129 ): 130 return provider.message() 131 try: 132 summary = provider.description() 133 except: 134 summary = None 135 logger >> "got summary " + str(summary) 136 if summary is None: 137 summary = "<variable is not NSException>" 138 return str(summary) 139 return "Summary Unavailable" 140 141 142def __lldb_init_module(debugger, dict): 143 debugger.HandleCommand( 144 "type summary add -F NSException.NSException_SummaryProvider NSException" 145 ) 146