如何找出谁是方法或函数的调用者?

时间:2009-09-03 15:05:53

标签: objective-c cocoa debugging methods program-flow

我想编写一个有助于打印有用信息的调试函数或方法。当它被调用时,我需要:

  • 调用对象的内存地址(如果是对象调用)
  • 调用方的方法签名(或方法名称)或函数名称
  • 拥有该方法或功能的类名

是否可以在不传递大量参数的情况下获取此信息?

我想做类似的事情:

debug();

然后进入每个方法和函数,并帮助打印出有关正在发生的事情的有用信息。

5 个答案:

答案 0 :(得分:3)

我的第一直觉是建议使用gdb和断点,因为大多数信息都可以在堆栈跟踪中使用。但是,如果你真的想看到它打印出来,有办法近似你在说什么

预处理器识别 __PRETTY_FUNCTION__ 宏以打印函数/方法名称,它适用于Objective-C方法。如果在每个感兴趣的方法中打印方法名称和self的值,那么你几乎已经产生了一个穷人的堆栈跟踪。

尝试在标题中包含 #define ,每个文件都包含以下内容:

#define METHOD() printf("%s\t0x%x\n", __PRETTY_FUNCTION__, (unsigned int)self)

然后只要您想要打印该信息,就包括这一行:

METHOD();

输出看起来像这样:

-[MyClass initWithFoo:bar:] 0x12345678

正如我所提到的,这种方法可能会产生大量的输出,而gdb可能是一个更实用的选择。

答案 1 :(得分:2)

  1. 在您要调试的方法上设置symbolic breakpoint
  2. 如果您需要在堆栈中向上移动(以查看方法调用的来源),您可以使用Xcode调试器,或者如果您想要自动化它,请使用backtrace n重新启动堆栈n帧数。

答案 2 :(得分:2)

我使用Karl Kraft的DebugLog

答案 3 :(得分:1)

抱歉,我没有完整的答案,只是一些相关的信息。

NSThread定义了一种方法,可以获得非符号化的回溯,callStackReturnAddresses。在10.6中,它还会为您提供满足第二和第三次请求的字符串callStackSymbols

获取调用对象的地址很有趣,但并不完全简单。这将涉及走向堆栈并挑选接收器对象通常存储的位置如果它存储在ARM上的通常位置。为此,您(或某人)需要了解ARM的调用约定,这些约定可能记录在某个地方的ARM ABI(应用程序二进制接口)中。我不知道ARM。这在i386上是可行的,而不是在ppc上。

答案 4 :(得分:0)

您可以使用backtrace(3) API找出您的方法或功能。获得调用对象(如果有的话)会更加困难。