在实习中,遇到了一些问题。问下有没有大佬帮忙解答一下~ 有个触发器被指针 A 与 B 注册为回调函数,我要在触发器函数内查看是 A 调用了还是 B 调用了该触发器。 如果不添加额外的引用参数(自研引擎,不好改),该怎么实现呢?
1
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 |
2
heijiaotuan123 2022-05-31 17:26:39 +08:00
|
4
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 |