如何让 backtrace()/backtrace_symbols() 打印函数名称?
- 2024-11-05 08:37:00
- admin 原创
- 30
问题描述:
Linux 特有的backtrace()
和backtrace_symbols()
允许您生成程序的调用跟踪。但是,它只打印函数地址,而不是程序的名称。我怎样才能让它们也打印函数名称?我尝试使用 和 编译程序-g
。-ggdb
下面的测试用例只打印以下内容:
回溯 ------------
复制代码
复制代码
/lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413]
复制代码
----------------------
我希望前两项也显示函数名称,foo
并且main
代码:
#include <execinfo.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
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 ------------
";
static const char end[] = "----------------------
";
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, "
", 1);
}
full_write(STDERR_FILENO, end, strlen(end));
free(bt_syms);
}
void foo()
{
print_backtrace();
}
int main()
{
foo();
return 0;
}
解决方案 1:
这些符号取自动态符号表;您需要选择-rdynamic
,gcc
它会让链接器传递一个标志,确保所有符号都放在表中。
(请参阅GCC 手册的“链接选项”页面,和/或glibc 手册的“回溯”页面。)
解决方案 2:
使用addr2line 命令将可执行文件地址映射到源代码文件名+行号。-f
同时提供获取函数名称的选项。
或者,尝试libunwind。
解决方案 3:
Ian Lance Taylor 编写的 Libbacktrace 非常出色,解决了这个问题。它处理堆栈展开,并支持普通 ELF 符号和 DWARF 调试符号。
Libbacktrace 不需要导出所有符号,这会很丑陋,而且 ASLR 不会破坏它。
Libbacktrace 最初是 GCC 发行版的一部分。现在,可以在 Github 上找到独立版本:
https://github.com/ianlancetaylor/libbacktrace
解决方案 4:
提升回溯
非常方便,因为它可以打印以下两者:
未损坏的 C++ 函数名称
行号
自动为您。
使用总结:
#define BOOST_STACKTRACE_USE_ADDR2LINE
#include <boost/stacktrace.hpp>
std::cout << boost::stacktrace::stacktrace() << std::endl;
我已经为它提供了一个最小的可运行示例和许多其他方法:用 C 或 C++ 打印调用堆栈
解决方案 5:
顶部的答案有一个错误,如果 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;
}
}
相关推荐
热门文章
项目管理软件有哪些?
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件
热门标签
云禅道AD