linux打印函数名,如何使backtrace()/ backtrace_symbols()打印函数名?

如何使backtrace()/ backtrace_symbols()打印函数名?

Linux特定的backtrace()和backtrace_symbols()允许你产生程序的调用轨迹。 但是,它只打印function地址,而不是我的程序的名称。 我怎样才能让他们打印函数名称呢? 我试着用-g和-ggdb编译程序。 下面的testing用例只是打印这个:

后退------------

./a.out()[0x8048616]

./a.out()[0x8048623]

/lib/libc.so.6(__libc_start_main+0xf3)[0x4a937413]

./a.out()[0x8048421]

----------------------

我想要前两个项目也显示函数名称, foo和main

码:

#include #include #include #include #include static void full_write(int fd, const char *buf, size_t len) { while (len > 0) { ssize_t ret = write(fd, buf, len); if ((ret == -1) && (errno != EINTR)) break; buf += (size_t) ret; len -= (size_t) ret; } } void print_backtrace(void) { static const char start[] = "BACKTRACE ------------\n"; static const char end[] = "----------------------\n"; void *bt[1024]; int bt_size; char **bt_syms; int i; bt_size = backtrace(bt, 1024); bt_syms = backtrace_symbols(bt, bt_size); full_write(STDERR_FILENO, start, strlen(start)); for (i = 1; i < bt_size; i++) { size_t len = strlen(bt_syms[i]); full_write(STDERR_FILENO, bt_syms[i], len); full_write(STDERR_FILENO, "\n", 1); } full_write(STDERR_FILENO, end, strlen(end)); free(bt_syms); } void foo() { print_backtrace(); } int main() { foo(); return 0; }

符号取自dynamic符号表; 你需要gcc的-rdynamic选项,这使得它传递一个标志给链接器,确保所有的符号都被放置在表格中。

(请参阅GCC手册的链接选项页面和/或glibc手册的Backtraces页面。)

使用addr2line命令将可执行文件地址映射到源代码文件名+行号。 给出-f选项以获取函数名称。

或者,尝试libunwind 。

Ian Lance Taylor的优秀Libbacktrace解决了这个问题。 它处理堆栈展开,并支持普通的ELF符号和DWARFdebugging符号。

Libbacktrace不需要导出所有符号,这将是丑陋的,ASLR不会打破它。

Libbacktrace最初是GCC发行版的一部分。 现在,在Github上可以find一个独立的版本:

在顶部的答案有一个错误,如果ret == -1和errno是EINTER,你应该再试一次,但是不要把复制的ret计算在内(如果你不喜欢它,就不要为此设置一个帐户)

static void full_write(int fd, const char *buf, size_t len) { while (len > 0) { ssize_t ret = write(fd, buf, len); if ((ret == -1) { if (errno != EINTR)) break; //else continue; } buf += (size_t) ret; len -= (size_t) ret; } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:我们首先将用最基本的编译方式将他们编译成一个可执行文件并执行,如下: gcc -g -rdynamic backtrace.c add.c dump.c -o backtrace ./backtrace =========>>>catch signal 11 <<<========= Dump stack start... backtrace() returned 8 addresses \[00\] ./backtrace(dump+0x1f) \[0x400a9b\] \[01\] ./backtrace(signal_handler+0x31) \[0x400b63\] \[02\] /lib/x86_64-linux-gnu/libc.so.6(+0x36150) \[0x7f86afc7e150\] \[03\] ./backtrace(add1+0x1a) \[0x400a3e\] \[04\] ./backtrace(add+0x1c) \[0x400a71\] \[05\] ./backtrace(main+0x2f) \[0x400a03\] \[06\] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) \[0x7f86afc6976d\] \[07\] ./backtrace() \[0x400919\] Dump stack end... 段错误 (核心已转储) 。 引用\[2\]:  backtrace_symbols生成的字符串占用的内存是malloc出来的,但是是一次性malloc出来的,释放是只需要一次性释放返回的二级指针即可。 void backtrace_symbols_fd(void *const *buffer, int size, int fd); 。 引用\[3\]:其中参数 -L. -ladd为编译时链接当前目录的libadd.so;参数-Wl,-rpath=.为指定程序执行时动态链接库搜索路径为当前目录,否则会出现执行找不到libadd.so的错误。然后执行backtrace程序结果如下: ./backtrace =========>>>catch signal 11 <<<========= Dump stack start... backtrace() returned 8 addresses \[00\] ./backtrace(dump+0x1f) \[0x400a53\] \[01\] ./backtrace(signal_handler+0x31) \[0x400b1b\] \[02\] /lib/x86_64-linux-gnu/libc.so.6(+0x36150) \[0x7f8583672150\] \[03\] ./libadd.so(add1+0x1a) \[0x7f85839fa5c6\] \[04\] ./libadd.so(add+0x1c) \[0x7f85839fa5f9\] \[05\] ./backtrace(main+0x2f) \[0x400a13\] \[06\] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) \[0x7f858365d76d\] \[07\] ./backtrace() \[0x400929\] Dump stack end... 段错误 (核心已转储) 。 问题:backtrace_symbols_fd函数的作用是什么? 回答: backtrace_symbols_fd函数的作用是将backtrace函数返回的地址信息转换成可读的字符串,并将其写入指定的文件描述符中。\[2\]这个函数的参数包括一个指向地址数组的指针,数组的大小和一个文件描述符。函数会将地址数组中的每个地址转换成对应的函数名和偏移量,并将结果写入指定的文件描述符中。 #### 引用[.reference_title] - *1* *3* [c语言 backtrace](https://blog.csdn.net/w1050321758/article/details/125833542)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [backtrace函数](https://blog.csdn.net/weixin_33672400/article/details/93449156)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值