gpt4 book ai didi

c - Linux 上 backtrace() 的替代方案,可以查找静态函数的符号

转载 作者:行者123 更新时间:2023-11-30 16:42:18 26 4
gpt4 key购买 nike

在手册页中,Linux 上的 backtrace() 函数显示:

Note that names of "static" functions are not exposed, and won't be available in the backtrace.

但是,启用调试符号 (-g) 后,addr2linegdb 等程序仍然可以获得静态函数的名称。有没有办法从进程本身中以编程方式获取静态函数的名称?

最佳答案

是的,通过使用例如检查其自己的可执行文件( /proc/self/exe ) libbfd或 ELF 文件解析库,用于解析实际符号本身。本质上,您编写的 C 代码可以完成类似的事情

env LANG=C LC_ALL=C readelf -s executable  | awk '($5 == "LOCAL" && $8 ~ /^[^_]/ && $8 !~ /\./)'

据我所知,Linux 中的动态链接器接口(interface) ( <dlfcn.h> ) 不会返回静态(本地)符号的地址。

一个简单且相当强大的方法是执行 readelfobjdump从你的程序中。请注意,您不能给出 /proc/self/exe这些的伪文件路径,因为它始终引用进程自己的可执行文件。相反,你必须使用例如。 realpath("/proc/self/exe", NULL)要获取当前可执行文件的动态分配的绝对路径,您可以提供给命令。您肯定还想确保环境包含 LANG=CLC_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 }
};

或许可以在头文件中导出一个简单的搜索函数,这样当链接最终的可执行文件时,它就可以轻松有效地访问本地符号数组。

它确实复制了一些数据,因为相同的信息已经存在于可执行文件中,如果我没记错的话,您必须首先将最终的可执行文件与 stub 数组链接起来以获得符号的实际地址,然后重新链接使用符号数组,这使得编译时有点麻烦。但它避免了对 binutils 的运行时依赖。 .

关于c - Linux 上 backtrace() 的替代方案,可以查找静态函数的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45877691/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com