Icon Xprobe 实时内存浏览器

更新: 之前作为 Xcode 插件的功能已经重新组织成一个 Swift 包,以便在其他应用程序中使用。 在客户端应用程序中使用 Xprobe 产品,在服务器端使用 XprobeUI 产品。

XprobePlugin 可以让您查看应用程序内部的对象,既可以深入到 ivar 级别的详细信息,也可以全局地查看主要对象的图及其连接方式。 这个显示可以实时动画,用红色突出显示正在被消息传递的对象,以及消息流经的路径。 这是通过执行“扫描”来自动完成的,以查找一组种子引用的所有对象、它们引用的对象、以及这些对象引用的对象,依此类推,构建一个实时对象列表,可以在 Xcode 中显示。

Icon

在模拟器中,内存扫描器从插件内部的一个 bundle 中加载,使用 lldb,无需更改应用程序的工程源代码。 要使用该插件,请构建此项目并重启 Xcode。 您的应用程序运行后,使用菜单项“Product/Xprobe/Load”加载应用程序的初始内存扫描视图。 如果您是插件开发者,您可以使用“Product/Xprobe/Xcode”来检查 Xcode 应用程序本身的对象。

然后,您可以使用模式将列出的对象过滤到应用程序或其方法中。 如果没有与模式匹配的对象,并且它是一个类名,则会显示该类名。 以 '+' 或 '-' 开头的模式将在链接到应用程序的所有类中搜索与该模式匹配的方法。 可以输入以 "0x" 开头的原始指针来检查作为参数传递给跟踪的对象。 您还可以输入以 "seed." 开头的对象“路径”,从您浏览应用程序时记录的路径中,以便您可以轻松地找到返回对象的路径。

如果您安装了 injectionforxcode 插件,Xprobe 将允许您针对选定的实例评估 Objective-C 或 Swift 代码,如果您有源代码,可以记录或修改对象在运行时的任何状态。

最新消息

现在,Xprobe.mm 可以在发生错误时将您的应用程序快照保存到独立的 html 文件中。 这会执行扫描,并可以记录错误发生时您的应用程序的状态,以供以后分析。 ReactNative 示例项目 "TickTackToe" 的示例快照文件可以 在此处查看

要拍摄快照,请在您的应用程序中包含 Xprobe.mm 并使用以下调用

    [Xprobe snapshot:@"/path/to/snapshot.html.gz" seeds:@[app delegate, rootViewController]];

如果您遇到困难,您可以使用附加的 excluding:(NSString *)pattern 参数来更改不捕获的类名称的模式。 此参数的默认值为

    @"^(?:UI|NS((Object|URL|Proxy)$|Text|Layout|Index|.*(Map|Data|Font))|Web|WAK|SwiftObject|XC|IDE|DVT|Xcode3|IB|VK)"

其余的功能最好以一系列要点形式列出

Icon

单击对象的链接以查看其 ivar 内容。

再次单击链接以关闭详细视图。

单击超类链接以查看其 ivars

单击 ivar 名称以从应用程序刷新其值

单击 ivar 值以编辑并在应用程序中设置其值

可以查看类的属性、方法和任何协议。

可以搜索方法列表(也可以找到超类方法)

使用“trace”链接开始记录对该实例上的方法的调用。

要查看对象的所有跟踪方法,请单击每个类上的跟踪。

可以使用正则表达式过滤跟踪输出

子视图链接将递归显示视图下的子视图树。

当对象是视图时,“render”链接将捕获图像。

siblings 链接将显示找到的所有共享对象类的对象。

通过在搜索字段中键入回车来刷新对象列表,以强制进行新的扫描。

按下 Graph 按钮将打开最重要的对象以及直接链接到它们的任何“kit”对象的摘要视图,这些对象取自上次扫描。

如果对象是一个视图(响应“subviews”),则它表示为一个正方形。

图形显示需要您的计算机上安装 "Graphviz/dot"

单击对象以查看其当前内容,如上所述。

可以应用对要包含哪些对象的不同过滤。

“Animate Messages”会在对象上放置一个跟踪,使它们在被消息传递时显示“红色”。

可以将图形导出为 Graphviz 或 .png 格式以进行打印。

遗憾的是,目前对 Swift 的支持有限,因为 ivar_getTypeEncoding() 为 ivar 字段返回 NULL,阻止它们参与“扫描”。

在设备上使用。

Xprobe 的工作原理是在模拟器中加载一个 bundle,该 bundle 在加载时连接到 Xcode。 应用程序通过实现以下类别来向 Xprobe 公布其种子节点列表

    @implementation Xprobe(Seeding)

    + (NSArray *)xprobeSeeds {
        UIApplication *app = [UIApplication sharedApplication];
        NSMutableArray *seeds = [NSMutableArray arrayWithObject:app];
        [seeds addObjectsFromArray:[app windows]];

        // support for cocos2d
        Class ccDirectorClass = NSClassFromString(@"CCDirector");
        CCDirector *ccDirector = [ccDirectorClass sharedDirector];
        if ( ccDirector )
            [seeds addObject:ccDirector];

        return seeds;
    }

    @end

或者对于 OSX

    + (NSArray *)xprobeSeeds {
        NSApplication *app = [NSApplication sharedApplication];
        NSMutableArray *seeds = [[app windows] mutableCopy];
        if ( app.delegate )
            [seeds insertObject:app.delegate atIndex:0];
        return seeds;
    }

一旦初始化了一个应用程序,调用 [Xprobe connectTo:"your.ip.address" retainObjects:YES] 以连接到在 Xcode 内部运行的 TCP 服务器。 retainObjects: 参数指定是否保留在扫描中找到的对象。 这将使 Xprobe 更加可靠,但会影响应用程序中的对象生命周期。 此后,调用 [Xprobe search:@""] 从这些对象开始执行初始扫描,以查找根对象。 每次调用“search:”或更改对象类过滤器时,都会重新执行扫描。 应用程序需要使用 Xprobe 和 Xtrace.{h,mm} 构建。

在这个干净的 “strong” 和 “weak” 指针的时代,如果对象对种子可见,扫描看起来非常可靠。 一些遗留类行为不端,并使用“assign”属性,这些属性可能包含指向已分配对象的指针。 为了避免扫描这些类的 ivar,Xprobe 有一个排除过滤器,可以在类别中覆盖(带有警告)

    static NSString *swiftPrefix = @"_TtC";

    @implementation Xprobe(ExclusionOverride)

    + (BOOL)xprobeExclude:(NSString *)className {
        static NSRegularExpression *excluded;
        if ( !excluded )
            excluded = [NSRegularExpression xsimpleRegexp:@"^(_|NS|XC|IDE|DVT|Xcode3|IB|VK|WebHistory)"];
        return [excluded xmatches:className] && ![className hasPrefix:swiftPrefix];
    }
    
    @end

这些排除允许 Xprobe 在 Xcode 本身内部干净地工作,如果您是插件开发者,这会派上用场。 对于任何建议或反馈,您可以通过 xprobe at johnholdsworth.com 联系作者。 主要版本将在 Twitter 上宣布 @Injection4Xcode.

使用 Swift 2.3+,Xprobe 不再能够扫描没有属性的 ivar,即不继承自 NSObject 的类。

源文件

Xprobe.{h,mm} - 快照所需的核心 Xprobe 功能 IvarAccess.h - 按名称访问类 ivar 所需的例程 Xprobe+Service.mm - 连接到 Xcode 的可选交互式服务

许可

版权所有 (c) 2014-5 John Holdsworth。 许可用于下载、修改和在 Objectice-C 应用程序开发期间的任何使用,重新分发只能通过公共 repo github,但包括此版权声明。 对于使用您的应用程序的二进制重新分发,请 取得联系

此版本包含一个经过轻微修改的优秀 canviz 库,用于在 HTML 画布中渲染 “dot” 文件,该库受 MIT 许可证的约束。 更改是将节点的 ID 传递到节点标签标签(第 212 行),反转节点和链接它们的线条的渲染(第 406 行)并存储边缘路径,以便它们可以在 “canviz-0.1/canviz.js” 中着色(第 66 和 303 行)。

它现在还包括 CodeMirror JavaScript 编辑器,用于使用 MIT 许可证下的注入评估的代码。

一如既往

本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途适用性和非侵权性的保证。 在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼或其他诉讼中,因本软件或本软件的使用或其他交易而产生或与之相关的。