brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · b752021 Raw
190 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 NSData9# 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 length for an NSData, so they need not24# obey the interface specification for synthetic children providers25 26 27class NSConcreteData_SummaryProvider:28    def adjust_for_architecture(self):29        pass30 31    def __init__(self, valobj, params):32        logger = lldb.formatters.Logger.Logger()33        logger >> "NSConcreteData_SummaryProvider __init__"34        self.valobj = valobj35        self.sys_params = params36        if not (self.sys_params.types_cache.NSUInteger):37            if self.sys_params.is_64_bit:38                self.sys_params.types_cache.NSUInteger = (39                    self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)40                )41            else:42                self.sys_params.types_cache.NSUInteger = (43                    self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)44                )45        self.update()46 47    def update(self):48        self.adjust_for_architecture()49 50    # one pointer is the ISA51    # then there are 32 bit worth of flags and other data52    # however, on 64bit systems these are padded to be a full53    # machine word long, which means we actually have two pointers54    # worth of data to skip55    def offset(self):56        return 2 * self.sys_params.pointer_size57 58    def length(self):59        logger = lldb.formatters.Logger.Logger()60        logger >> "NSConcreteData_SummaryProvider length"61        size = self.valobj.CreateChildAtOffset(62            "count", self.offset(), self.sys_params.types_cache.NSUInteger63        )64        logger >> str(size)65        logger >> str(size.GetValueAsUnsigned(0))66        return size.GetValueAsUnsigned(0)67 68 69class NSDataUnknown_SummaryProvider:70    def adjust_for_architecture(self):71        pass72 73    def __init__(self, valobj, params):74        logger = lldb.formatters.Logger.Logger()75        logger >> "NSDataUnknown_SummaryProvider __init__"76        self.valobj = valobj77        self.sys_params = params78        self.update()79 80    def update(self):81        self.adjust_for_architecture()82 83    def length(self):84        logger = lldb.formatters.Logger.Logger()85        logger >> "NSDataUnknown_SummaryProvider length"86        stream = lldb.SBStream()87        self.valobj.GetExpressionPath(stream)88        logger >> stream.GetData()89        num_children_vo = self.valobj.CreateValueFromExpression(90            "count", "(int)[" + stream.GetData() + " length]"91        )92        logger >> "still in after expression: " + str(num_children_vo)93        if num_children_vo.IsValid():94            logger >> "wow - expr output is valid: " + str(95                num_children_vo.GetValueAsUnsigned()96            )97            return num_children_vo.GetValueAsUnsigned(0)98        logger >> "invalid expr output - too bad"99        return "<variable is not NSData>"100 101 102def GetSummary_Impl(valobj):103    global statistics104    logger = lldb.formatters.Logger.Logger()105    logger >> "NSData GetSummary_Impl"106    (107        class_data,108        wrapper,109    ) = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(110        valobj, statistics111    )112    if wrapper:113        logger >> "got a wrapper summary - using it"114        return wrapper115 116    name_string = class_data.class_name()117    logger >> "class name: " + name_string118    if (119        name_string == "NSConcreteData"120        or name_string == "NSConcreteMutableData"121        or name_string == "__NSCFData"122    ):123        wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)124        statistics.metric_hit("code_notrun", valobj)125    else:126        wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)127        statistics.metric_hit(128            "unknown_class", valobj.GetName() + " seen as " + name_string129        )130    return wrapper131 132 133def NSData_SummaryProvider(valobj, dict):134    logger = lldb.formatters.Logger.Logger()135    logger >> "NSData_SummaryProvider"136    provider = GetSummary_Impl(valobj)137    logger >> "found a summary provider, it is: " + str(provider)138    if provider is not None:139        try:140            summary = provider.length()141        except:142            summary = None143        logger >> "got a summary: it is " + str(summary)144        if summary is None:145            summary = "<variable is not NSData>"146        elif isinstance(summary, str):147            pass148        else:149            if summary == 1:150                summary = "1 byte"151            else:152                summary = str(summary) + " bytes"153        return summary154    return "Summary Unavailable"155 156 157def NSData_SummaryProvider2(valobj, dict):158    logger = lldb.formatters.Logger.Logger()159    logger >> "NSData_SummaryProvider2"160    provider = GetSummary_Impl(valobj)161    logger >> "found a summary provider, it is: " + str(provider)162    if provider is not None:163        if isinstance(164            provider, lldb.runtime.objc.objc_runtime.SpecialSituation_Description165        ):166            return provider.message()167        try:168            summary = provider.length()169        except:170            summary = None171        logger >> "got a summary: it is " + str(summary)172        if summary is None:173            summary = "<variable is not CFData>"174        elif isinstance(summary, str):175            pass176        else:177            if summary == 1:178                summary = '@"1 byte"'179            else:180                summary = '@"' + str(summary) + ' bytes"'181        return summary182    return "Summary Unavailable"183 184 185def __lldb_init_module(debugger, dict):186    debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData")187    debugger.HandleCommand(188        "type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef"189    )190