在手册页上,Linux上的backtrace()函数说:
但是,启用debugging符号( -g )后,像addr2line和gdb这样的程序仍然可以获得静态函数的名称。 有没有办法从过程本身编程获取静态function的名称?
ARM平台上的SIGABRT信号没有回溯?
从catch块获取回溯
获取其他线程的回溯
使用malloc / free on callstack从Signal Handler回溯Linux 64位
如何使backtrace()/ backtrace_symbols()打印函数名?
为什么“echo l> / proc / sysrq-trigger”调用跟踪输出总是类似的?
问号是什么意思? 在Linux内核恐慌调用跟踪?
在共享库内的回溯函数
一个程序能读取自己的精灵部分吗?
如果你的可执行文件(和链接库)是用调试信息编译的(例如用-g标志指向gcc或g++ ),那么你可以在GCC里使用Ian Taylor的libbacktrace ( 在这里宣布) – 在这里看到它的代码
该库(BSD许可的免费软件)正在使用来自该进程链接的可执行文件和共享库的DWARF调试信息。 请参阅其自述文件。
请注意,如果您使用优化进行编译,则可以内联某些函数(即使没有在源代码中inline显式标记,并且static内联函数可能没有任何适当的自己的代码)。 那么回溯就不会讲很多关于他们的事情。
是的,通过使用例如libbfd或ELF文件解析库检查自己的可执行文件( /proc/self/exe )来解析实际的符号本身。 从本质上讲,你会写C代码,就像是类似的东西
env LANG=C LC_ALL=C readelf -s executable | awk '($5 == "LOCAL" && $8 ~ /^[^_]/ && $8 !~ /./)'
据我所知,Linux中的动态链接器接口( <dlfcn.h> )不会返回静态(本地)符号的地址。
一个简单且相当健壮的方法是从程序中执行readelf或objdump 。 请注意,您不能将/proc/self/exe伪文件路径给予这些路径,因为它始终引用进程自己的可执行文件。 相反,你必须使用例如。 realpath("/proc/self/exe",NULL)来获得一个动态分配给当前可执行文件的绝对路径,你可以提供给命令。 你也一定要确保环境包含LANG=C和LC_ALL=C ,这样命令的输出很容易解析(而不是本地化为当前用户喜欢的任何语言)。 这可能感觉有些不便,但只需要安装binutils包就可以工作,而且不需要更新程序或库来跟上最新的发展,所以我认为这是一个非常好的方法。
你想要一个例子吗?
一种简单的方法是在编译时用符号信息生成单独的数组。 基本上,在生成目标文件之后,通过在相关的目标文件上运行objdump或readelf动态生成一个单独的源文件,生成一个名称和指针的数组,类似于
const struct { const char *const name; const void *const addr; } local_symbol_names[] = { /* Filled in using objdump or readelf and awk,for example */ { NULL,NULL } };
也许在头文件中导出一个简单的搜索函数,这样当最终的可执行文件被链接时,它可以轻松高效地访问本地符号数组。
它会复制一些数据,因为相同的信息已经存在于可执行文件中,如果我没有记错的话,你必须首先链接最后一个可执行文件和一个存根数组,以获得符号的实际地址,然后用符号数组,使它在编译时有点麻烦..但是它避免了运行时对binutils依赖。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。