Objective c 跟踪所有ObjC方法调用?

Objective c 跟踪所有ObjC方法调用?,objective-c,debugging,Objective C,Debugging,有时,当看到别人的大型Objective-C程序时,很难知道从哪里开始 在这种情况下,我认为记录对每个非Apple方法的每次调用会有所帮助 有办法吗?基本上,在某个中心位置进行一次更改,并记录调用的每个方法。最好仅限于非Apple方法。您可以向objc_msgSend()添加一个符号断点,并让它记录第二个参数而不停止 不过,如何用自己的方法来实现这一点是一个棘手的任务。如果您可以检查正在调用的类名,并施展一些魔法,只为类前缀与您自己的前缀匹配的调用设置一个条件断点?这是一个有趣的问题。如果解决方

有时,当看到别人的大型Objective-C程序时,很难知道从哪里开始

在这种情况下,我认为记录对每个非Apple方法的每次调用会有所帮助


有办法吗?基本上,在某个中心位置进行一次更改,并记录调用的每个方法。最好仅限于非Apple方法。

您可以向
objc_msgSend()
添加一个符号断点,并让它记录第二个参数而不停止


不过,如何用自己的方法来实现这一点是一个棘手的任务。如果您可以检查正在调用的类名,并施展一些魔法,只为类前缀与您自己的前缀匹配的调用设置一个条件断点?

这是一个有趣的问题。如果解决方案支持多个执行线程,并且有某种调用时间线可以报告一段时间内的活动(可能特别是以某种方式绘制的用户事件),那么答案会更有趣

我通常启动调试器,在主入口点设置一个断点(例如,-ApplicationIDFinishLaunching:withOptions:),然后在调试器中遍历它

在OSX上,还有一些命令行工具(例如sample和heap)可以提供一些见解

看起来某种与仪器的集成可能真的很酷,但我不知道有什么东西能完全满足你的需求(我现在也想要它)


如果要记录线程号、呼叫地址和一些帧细节,那么这些片段似乎可以用来绘制呼叫时间线。在苹果的脚本中,应该存在确定适当库(苹果提供的或第三方的)的逻辑。

我不认为记录每个调用都实用到有用的程度,但在这方面有一个建议

另一方面,如果它是一个大型程序,最好有一些文档或介绍注释,以便人们开始使用代码

在任何情况下,每个Cocoa应用程序都有一个ApplicationIDFinishLaunching…方法。这是一个很好的起点。某些应用程序的主体(或“主窗口”)类也在Info.plist文件中定义。这两种情况都可能会提示您哪些类(特别是视图控制器)是最重要的类,以及在程序运行时哪些方法可能具有长堆栈跟踪。就像游戏引擎中的游戏循环,或者其他一些经常调用的方法。通过在这样的方法中放置断点并查看调试器中的堆栈跟踪,您可以大致了解发生了什么

如果它是一个UI密集型应用程序,查看其中使用的NIB文件和类也可能有助于确定您可能正在寻找的应用程序功能的部分

另一个选项是启动时间分析器仪器并选中
隐藏缺失符号
隐藏系统库
复选框。这不仅可以让您鸟瞰程序内部调用的方法,还可以锁定最常调用的方法


通过在时间档案器记录打开的情况下与程序交互,您还可以很容易地识别程序功能的不同部分,并将它们与您的操作关联起来。

您可以将环境变量NSObjCMessageLoggingEnabled设置为YES。这将在/tmp/msgSends xxx文件夹中写入所有消息发送的日志。

Instruments允许您构建自己的“Instruments”,它们实际上只是伪装的脚本。使用菜单选项Instrument>>Build New Instrument(仪器>>构建新仪器)并选择要跟踪的库、点击特定功能时要录制的内容等选项。尽情享受吧

可能的重复也可能会引起兴趣:好的,我在objc_msgSend()中打断,如何获取第二个参数?请注意,我不想发送任何objective C消息:(@William-如何获取第二个参数取决于您的目标,因为模拟器的x86 ABI与设备的ARM ABI不同。您必须从正确的处理器寄存器或堆栈位置获取值。一天结束时,我想您必须问问自己,这是否真的值得。如果值得,请搜索darwin ABI d文档。这是一个很难找到的bug的救命稻草。谢谢。@alex gray,np。它是什么类型的bug?它在哪里?/tmp/msgSends xxx在哪里?就像它说的那样…在/tmp目录中。下面是一个从目录结构角度看UNIX文件系统可能是什么样子的示例: