C++ 如何在当前函数内 知道是哪个函数调用了当前函数

2022-05-31 16:49:42 +08:00
 mjy2

在实习中,遇到了一些问题。问下有没有大佬帮忙解答一下~ 有个触发器被指针 A 与 B 注册为回调函数,我要在触发器函数内查看是 A 调用了还是 B 调用了该触发器。 如果不添加额外的引用参数(自研引擎,不好改),该怎么实现呢?

1387 次点击
所在节点    问与答
4 条回复
Donahue
2022-05-31 17:05:54 +08:00
https://stackoverflow.com/questions/3899870/print-call-stack-in-c-or-c
找到了一些可能有用的信息~

google 关键字 c++ call stack
heijiaotuan123
2022-05-31 17:26:39 +08:00
mjy2
2022-05-31 18:06:45 +08:00
@Donahue 看了下是返回内存地址,那么每次运行的话,得出的内存地址都会不同嘛
anonymous256
2022-05-31 18:10:57 +08:00
在你的触发器函数里面,解开函数调用栈就可以了。三种常用的办法:

1. gcc 内置宏__builtin_return_address:非常粗略的低级方法。这会在堆栈上的每一帧上获得函数的返回地址。注意:只是地址,不是函数名。所以需要额外的处理来获取函数名。
2. glibc 的 backtrace 和 backtrace_symbols:可以获取调用堆栈上函数的实际符号名称。
3. libunwind 库

参考自: https://eli.thegreenplace.net/2015/programmatic-access-to-the-call-stack-in-c/

根据上述文章提到的办法,采用 libunwind 库,我简单修改了下它的代码:
1. 代码示例

```
// example.cpp

#include <libunwind.h>
#include <stdio.h>

// Call this function to get a backtrace.
void backtrace() {
unw_cursor_t cursor;
unw_context_t context;

// Initialize cursor to current frame for local unwinding.
unw_getcontext(&context);
unw_init_local(&cursor, &context);

// Unwind frames one by one, going up the frame stack.
while (unw_step(&cursor) > 0) {
unw_word_t offset, pc;
unw_get_reg(&cursor, UNW_REG_IP, &pc);
if (pc == 0) {
break;
}
printf("0x%lx:", pc);

char sym[256];
if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {
printf("(caller function: %s+, offset: 0x%lx)\n", sym, offset);
} else {
printf(" -- error: unable to obtain symbol name for this frame\n");
}
}
}

void foo1() {
backtrace(); // <-------- backtrace here!
}

void foo2() {
backtrace(); // <-------- backtrace here!
}


int main(int argc, char **argv) {
foo1(); // <-----在函数 foo1()和 foo2()中可以看到整个的调用栈。
printf("\n");
foo2();
return 0;
}

````

2. 编译前安装依赖(以 ubuntu 为例):
sudo apt install libunwind-dev

3. 编译指令:
g++ -o example example.cpp -L /usr/local/lib -lunwind

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/856496

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX