3

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

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

是否有可能在不传递一大堆参数的情况下获取这些信息?

我想做类似的东西:

debug();

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

4

5 回答 5

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 可能是一个更务实的选择。

于 2009-09-03T15:37:29.497 回答
2

我使用 Karl Kraft 的DebugLog

于 2009-09-03T15:55:50.900 回答
2
  1. 在您感兴趣的调试方法上设置符号断点。
  2. 如果您需要在堆栈中向上移动(以查看方法调用的来源),您可以使用 Xcode 调试器,或者如果您想自动化它,使用在堆栈帧数backtrace n中向上移动。n
于 2009-09-03T15:35:25.223 回答
1

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

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

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

于 2009-09-03T16:02:41.047 回答
0

您可以使用backtrace(3) API 找出调用您的方法或函数。但是,获取调用对象(如果有的话)要困难得多。

于 2009-09-03T18:01:12.190 回答