129 lines · python
1"""2LLDB AppKit formatters3 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-exception7"""8# example summary provider for NSNotification9# the real summary is now C++ code built into LLDB10import lldb.runtime.objc.objc_runtime11import lldb.formatters.metrics12import CFString13import lldb14import lldb.formatters.Logger15 16statistics = lldb.formatters.metrics.Metrics()17statistics.add_metric("invalid_isa")18statistics.add_metric("invalid_pointer")19statistics.add_metric("unknown_class")20statistics.add_metric("code_notrun")21 22 23class NSConcreteNotification_SummaryProvider:24 def adjust_for_architecture(self):25 pass26 27 def __init__(self, valobj, params):28 logger = lldb.formatters.Logger.Logger()29 self.valobj = valobj30 self.sys_params = params31 if not (self.sys_params.types_cache.id):32 self.sys_params.types_cache.id = self.valobj.GetType().GetBasicType(33 lldb.eBasicTypeObjCID34 )35 self.update()36 37 def update(self):38 logger = lldb.formatters.Logger.Logger()39 self.adjust_for_architecture()40 41 # skip the ISA and go to the name pointer42 def offset(self):43 logger = lldb.formatters.Logger.Logger()44 return self.sys_params.pointer_size45 46 def name(self):47 logger = lldb.formatters.Logger.Logger()48 string_ptr = self.valobj.CreateChildAtOffset(49 "name", self.offset(), self.sys_params.types_cache.id50 )51 return CFString.CFString_SummaryProvider(string_ptr, None)52 53 54class NSNotificationUnknown_SummaryProvider:55 def adjust_for_architecture(self):56 pass57 58 def __init__(self, valobj, params):59 logger = lldb.formatters.Logger.Logger()60 self.valobj = valobj61 self.sys_params = params62 self.update()63 64 def update(self):65 logger = lldb.formatters.Logger.Logger()66 self.adjust_for_architecture()67 68 def name(self):69 logger = lldb.formatters.Logger.Logger()70 stream = lldb.SBStream()71 self.valobj.GetExpressionPath(stream)72 name_vo = self.valobj.CreateValueFromExpression(73 "name", "(NSString*)[" + stream.GetData() + " name]"74 )75 if name_vo.IsValid():76 return CFString.CFString_SummaryProvider(name_vo, None)77 return "<variable is not NSNotification>"78 79 80def GetSummary_Impl(valobj):81 logger = lldb.formatters.Logger.Logger()82 global statistics83 (84 class_data,85 wrapper,86 ) = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(87 valobj, statistics88 )89 if wrapper:90 return wrapper91 92 name_string = class_data.class_name()93 logger >> "class name is: " + str(name_string)94 95 if name_string == "NSConcreteNotification":96 wrapper = NSConcreteNotification_SummaryProvider(valobj, class_data.sys_params)97 statistics.metric_hit("code_notrun", valobj)98 else:99 wrapper = NSNotificationUnknown_SummaryProvider(valobj, class_data.sys_params)100 statistics.metric_hit(101 "unknown_class", valobj.GetName() + " seen as " + name_string102 )103 return wrapper104 105 106def NSNotification_SummaryProvider(valobj, dict):107 logger = lldb.formatters.Logger.Logger()108 provider = GetSummary_Impl(valobj)109 if provider is not None:110 if isinstance(111 provider, lldb.runtime.objc.objc_runtime.SpecialSituation_Description112 ):113 return provider.message()114 try:115 summary = provider.name()116 except:117 summary = None118 logger >> "got summary " + str(summary)119 if summary is None:120 summary = "<variable is not NSNotification>"121 return str(summary)122 return "Summary Unavailable"123 124 125def __lldb_init_module(debugger, dict):126 debugger.HandleCommand(127 "type summary add -F NSNotification.NSNotification_SummaryProvider NSNotification"128 )129