brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 593554c Raw
160 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# summary provider for NSURL9import lldb10import ctypes11import lldb.runtime.objc.objc_runtime12import lldb.formatters.metrics13import CFString14import 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 a summary for an NSURL, so they need not24# obey the interface specification for synthetic children providers25 26 27class NSURLKnown_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.NSString):36            self.sys_params.types_cache.NSString = (37                self.valobj.GetTarget().FindFirstType("NSString").GetPointerType()38            )39        if not (self.sys_params.types_cache.NSURL):40            self.sys_params.types_cache.NSURL = (41                self.valobj.GetTarget().FindFirstType("NSURL").GetPointerType()42            )43        self.update()44 45    def update(self):46        logger = lldb.formatters.Logger.Logger()47        self.adjust_for_architecture()48 49    # one pointer is the ISA50    # then there is one more pointer and 8 bytes of plain data51    # (which are also present on a 32-bit system)52    # then there is a pointer to an NSString which is the url text53    # optionally, the next pointer is another NSURL which is the "base"54    # of this one when doing NSURLs composition (incidentally, NSURLs can55    # recurse the base+text mechanism to any desired depth)56    def offset_text(self):57        logger = lldb.formatters.Logger.Logger()58        return 24 if self.sys_params.is_64_bit else 1659 60    def offset_base(self):61        logger = lldb.formatters.Logger.Logger()62        return self.offset_text() + self.sys_params.pointer_size63 64    def url_text(self):65        logger = lldb.formatters.Logger.Logger()66        text = self.valobj.CreateChildAtOffset(67            "text", self.offset_text(), self.sys_params.types_cache.NSString68        )69        base = self.valobj.CreateChildAtOffset(70            "base", self.offset_base(), self.sys_params.types_cache.NSURL71        )72        my_string = CFString.CFString_SummaryProvider(text, None)73        if len(my_string) > 0 and base.GetValueAsUnsigned(0) != 0:74            # remove final " from myself75            my_string = my_string[0 : len(my_string) - 1]76            my_string = my_string + " -- "77            my_base_string = NSURL_SummaryProvider(base, None)78            if len(my_base_string) > 2:79                # remove @" marker from base URL string80                my_base_string = my_base_string[2:]81            my_string = my_string + my_base_string82        return my_string83 84 85class NSURLUnknown_SummaryProvider:86    def adjust_for_architecture(self):87        pass88 89    def __init__(self, valobj, params):90        logger = lldb.formatters.Logger.Logger()91        self.valobj = valobj92        self.sys_params = params93        self.update()94 95    def update(self):96        logger = lldb.formatters.Logger.Logger()97        self.adjust_for_architecture()98 99    def url_text(self):100        logger = lldb.formatters.Logger.Logger()101        stream = lldb.SBStream()102        self.valobj.GetExpressionPath(stream)103        url_text_vo = self.valobj.CreateValueFromExpression(104            "url", "(NSString*)[" + stream.GetData() + " description]"105        )106        if url_text_vo.IsValid():107            return CFString.CFString_SummaryProvider(url_text_vo, None)108        return "<variable is not NSURL>"109 110 111def GetSummary_Impl(valobj):112    logger = lldb.formatters.Logger.Logger()113    global statistics114    (115        class_data,116        wrapper,117    ) = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(118        valobj, statistics119    )120    if wrapper:121        return wrapper122 123    name_string = class_data.class_name()124    logger >> "class name is: " + str(name_string)125 126    if name_string == "NSURL":127        wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params)128        statistics.metric_hit("code_notrun", valobj)129    else:130        wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params)131        statistics.metric_hit(132            "unknown_class", valobj.GetName() + " seen as " + name_string133        )134    return wrapper135 136 137def NSURL_SummaryProvider(valobj, dict):138    logger = lldb.formatters.Logger.Logger()139    provider = GetSummary_Impl(valobj)140    if provider is not None:141        if isinstance(142            provider, lldb.runtime.objc.objc_runtime.SpecialSituation_Description143        ):144            return provider.message()145        try:146            summary = provider.url_text()147        except:148            summary = None149        logger >> "got summary " + str(summary)150        if summary is None or summary == "":151            summary = "<variable is not NSURL>"152        return summary153    return "Summary Unavailable"154 155 156def __lldb_init_module(debugger, dict):157    debugger.HandleCommand(158        "type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef"159    )160