捕获所有 Objective-C 消息并获取 Cocoa 运行时中的对象列表

Posted

技术标签:

【中文标题】捕获所有 Objective-C 消息并获取 Cocoa 运行时中的对象列表【英文标题】:Catch all Objective-C messages and get list of objects in Cocoa runtime 【发布时间】:2010-10-06 13:25:09 【问题描述】:

我需要捕获并记录 Cocoa 应用程序中的对象发送的所有消息。而且我还需要运行时对象实例的列表。有可能吗?

【问题讨论】:

对此,不禁要问:为什么?你真正想达到什么目标? 我要画cocoa app的对象图=) 【参考方案1】:

使用dtrace,它已经内置在系统中。请参阅 MacTech 的 this great introductory article。

Dtrace 是系统范围的标准机制,因此您可以记录活动。各种系统 API 通知内核,即每个系统调用、每个objc_msgSend 等都会生成一个可跟踪点,您可以将 dtrace 脚本传递给内核以记录这些活动。它非常强大。

作为练习,请将以下内容放入名为 objc.d 的文件中:

objc$target:::entry

    printf("[%s %s]\n", probemod,probefunc);

然后从命令行运行

$ sudo dtrace -q -s objc.d -p 3333

其中 3333 应该是一些 Cocoa 应用程序的 pid。您将获得发送到任何对象的每条消息的日志!呜呜!

【讨论】:

您确实应该将输出重定向到文件以供以后分析。这显然会迅速产生大量的数据。类似sudo dtrace -q -s objc.d -p 3333 > /tmp/allmethodcalls.txt 还请注意,上述内容不一定会捕获每个方法调用。输出速率对于 dtrace 来说太快了,并且在主动计算期间会丢失数千个。【参考方案2】:

您可以通过将NSObjCMessageLoggingEnabled 环境变量设置为YES 来记录应用程序中发送的每条Objective-C 消息。在 Xcode 中选择可执行文件,按 Cmd-I 显示检查器并在那里添加环境变量(参数选项卡)。 Obj-C 消息记录在 /tmp/msgSends-<pid> 中。完成后记得关闭设置,因为日志文件可能巨大

【讨论】:

您还可以复制当前方案并创建一个启用 msgSends 的新方案。在Run -> Arguments -> Environment variables 下。我建议共享该方案,以便团队中的其他人也可以使用它。 “僵尸”计划同样有用。【参考方案3】:

是的,这是可能的,objective-c 是高度动态的,您可以在运行时获得大量信息。仔细看看Objective-C Runtime Reference

【讨论】:

你还没有回答他的问题。哪些 Objective-C 运行时调用将允许记录发送到每个对象的每条消息? 是的,我认为捕获所有消息的唯一方法是用我的自定义方法替换 objc_msgSend 方法。 公平地说,这是一个与问题相匹配的答案

以上是关于捕获所有 Objective-C 消息并获取 Cocoa 运行时中的对象列表的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C try/catch异常处理机制原理。

如何使用 Objective-C 在 IOS 中读取和存储系统日志消息

为啥 Objective-C 不显示 OpenCV 捕获的视频的输出帧?

使用 XCTestCase Objective-C 进行多次测试性能

在objective-c中捕获内存泄漏的设计模式?

在am中定义消息集束,并在CO中验证之后抛出异常。