145 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 NSMachPort9# the real summary is now C++ code built into LLDB10import lldb11import ctypes12import lldb.runtime.objc.objc_runtime13import lldb.formatters.metrics14import 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# despite the similary to synthetic children providers, these classes are not23# trying to provide anything but the port number of an NSMachPort, so they need not24# obey the interface specification for synthetic children providers25 26 27class NSMachPortKnown_SummaryProvider:28 def adjust_for_architecture(self):29 pass30 31 def __init__(self, valobj, params):32 logger = lldb.formatters.Logger.Logger()33 self.valobj = valobj34 self.sys_params = params35 if not (self.sys_params.types_cache.NSUInteger):36 if self.sys_params.is_64_bit:37 self.sys_params.types_cache.NSUInteger = (38 self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)39 )40 else:41 self.sys_params.types_cache.NSUInteger = (42 self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)43 )44 self.update()45 46 def update(self):47 logger = lldb.formatters.Logger.Logger()48 self.adjust_for_architecture()49 50 # one pointer is the ISA51 # then we have one other internal pointer, plus52 # 4 bytes worth of flags. hence, these values53 def offset(self):54 logger = lldb.formatters.Logger.Logger()55 if self.sys_params.is_64_bit:56 return 2057 else:58 return 1259 60 def port(self):61 logger = lldb.formatters.Logger.Logger()62 vport = self.valobj.CreateChildAtOffset(63 "port", self.offset(), self.sys_params.types_cache.NSUInteger64 )65 return vport.GetValueAsUnsigned(0)66 67 68class NSMachPortUnknown_SummaryProvider:69 def adjust_for_architecture(self):70 pass71 72 def __init__(self, valobj, params):73 logger = lldb.formatters.Logger.Logger()74 self.valobj = valobj75 self.sys_params = params76 self.update()77 78 def update(self):79 logger = lldb.formatters.Logger.Logger()80 self.adjust_for_architecture()81 82 def port(self):83 logger = lldb.formatters.Logger.Logger()84 stream = lldb.SBStream()85 self.valobj.GetExpressionPath(stream)86 num_children_vo = self.valobj.CreateValueFromExpression(87 "port", "(int)[" + stream.GetData() + " machPort]"88 )89 if num_children_vo.IsValid():90 return num_children_vo.GetValueAsUnsigned(0)91 return "<variable is not NSMachPort>"92 93 94def GetSummary_Impl(valobj):95 logger = lldb.formatters.Logger.Logger()96 global statistics97 (98 class_data,99 wrapper,100 ) = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(101 valobj, statistics102 )103 if wrapper:104 return wrapper105 106 name_string = class_data.class_name()107 logger >> "class name is: " + str(name_string)108 109 if name_string == "NSMachPort":110 wrapper = NSMachPortKnown_SummaryProvider(valobj, class_data.sys_params)111 statistics.metric_hit("code_notrun", valobj)112 else:113 wrapper = NSMachPortUnknown_SummaryProvider(valobj, class_data.sys_params)114 statistics.metric_hit(115 "unknown_class", valobj.GetName() + " seen as " + name_string116 )117 return wrapper118 119 120def NSMachPort_SummaryProvider(valobj, dict):121 logger = lldb.formatters.Logger.Logger()122 provider = GetSummary_Impl(valobj)123 if provider is not None:124 if isinstance(125 provider, lldb.runtime.objc.objc_runtime.SpecialSituation_Description126 ):127 return provider.message()128 try:129 summary = provider.port()130 except:131 summary = None132 logger >> "got summary " + str(summary)133 if summary is None:134 summary = "<variable is not NSMachPort>"135 if isinstance(summary, str):136 return summay137 return "mach port: " + str(summary)138 return "Summary Unavailable"139 140 141def __lldb_init_module(debugger, dict):142 debugger.HandleCommand(143 "type summary add -F NSMachPort.NSMachPort_SummaryProvider NSMachPort"144 )145