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

发布于 2024-08-03 17:23:42 字数 265 浏览 10 评论 0原文

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

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

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

我想做一些类似:

debug();

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

I want to write a debug function or method that will help print useful information. When it is called, I need:

  • the memory address of the calling object (if called by an object)
  • the method signature of the caller (or the name of the method), or the name of the function
  • the class name that owns that method or function

Is it possible to get this information without passing a whole bunch of parameters?

I want to make something like:

debug();

which then goes into every method and function, and helps printing out useful informations about what's going on.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ˇ宁静的妩媚 2024-08-10 17:23:42

我的第一反应是建议使用 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 可能是一个更务实的选择。

My first instinct would be to suggest using gdb and breakpoints, since most of that information is available in a stack trace. However, if you really want to see it printed, there are ways to approximate what you're talking about

The preprocessor recognizes the __PRETTY_FUNCTION__ macro for printing the function/method name, and it works well for Objective-C methods. If you print the method name and the value of self at each method of interest, you've pretty much generated a poor man's stack trace.

Try including a #define like this in a header that every file that wants it includes:

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

Then just include this line whenever you want to print that information:

METHOD();

The output will look something like this:

-[MyClass initWithFoo:bar:] 0x12345678

As I mentioned, this type of approach is likely to produce huge amounts of output, and gdb is probably a more pragmatic option.

冰葑 2024-08-10 17:23:42
  1. 设置符号断点关于您有兴趣调试的方法。
  2. 如果您需要在堆栈中向上移动(以查看方法调用来自何处),您可以使用 Xcode 调试器,或者如果您想自动化它,请使用 backtrace n 在堆栈中向上移动 n 个帧。
  1. Set a symbolic breakpoint on the methods you are interested in debugging.
  2. If you need to move back up in the stack (to see where the method call came from) you can either use the Xcode Debugger, or if you want to automated it, use backtrace n to move back up in the stack n number of frames.
悲念泪 2024-08-10 17:23:42

我使用 Karl Kraft 的 DebugLog

I use Karl Kraft's DebugLog

左耳近心 2024-08-10 17:23:42

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

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

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

Sorry I don't have a full answer for you, just some relevant info.

NSThread defines a method that gets you an unsymbolicated backtrace, callStackReturnAddresses. In 10.6, it also will give you strings satisfying your second and third requests callStackSymbols.

Getting address of the calling object is interesting, but not totally simple. It's going to involve walking up the stack and picking out where the receiver object is usually stored if there is a usual place it's stored on ARM. For this you (or someone) would need to understand the calling conventions for ARM, which are probably documented in an ARM ABI (application binary interface) somewhere. I don't know ARM. This would be doable on i386, and not really on ppc.

花开柳相依 2024-08-10 17:23:42

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

You can use the backtrace(3) API to find out what method or function called you. Getting the calling object, if there was one, is much, much harder, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文