子进程abort追踪:GDB显示__GI_abort而非abort及地址获取问题
问题解答
1. 为何GDB显示__GI_abort而非abort?
这是GNU C库(glibc)的符号命名机制导致的:
abort是C标准定义的公开接口符号,属于弱符号或者是一个轻量包装函数,实际执行时会跳转到glibc内部的实现函数__GI_abort。- GDB会解析程序实际运行的底层符号,所以显示的是真正执行的
__GI_abort而非上层的包装符号abort。 - 前缀
__GI_是GNU Implementation的缩写,用来标识glibc内部的实现符号,和对外暴露的标准接口符号做区分。
2. 如何获取__GI_abort的地址?
直接在代码里写__GI_abort会报错,因为这个符号是glibc的内部符号,没有在公开头文件中声明。可以通过以下两种方式获取:
方法一:使用动态链接库函数dlsym
通过dlsym从libc中动态查询符号地址,需要包含<dlfcn.h>头文件,编译时链接dl库(加-ldl参数):
#include <dlfcn.h> #include <stdio.h> // 获取__GI_abort的地址 void* get_gi_abort_addr() { void* addr = dlsym(RTLD_DEFAULT, "__GI_abort"); if (!addr) { // 处理错误,打印具体报错信息 fprintf(stderr, "Failed to get __GI_abort address: %s\n", dlerror()); } return addr; }
RTLD_DEFAULT表示从当前进程的全局符号表中查找,会优先匹配当前加载的libc中的符号。- 也可以尝试
RTLD_NEXT,但RTLD_DEFAULT更直接对应进程正在使用的libc实例。
方法二:通过符号表工具预先获取地址(仅适合固定环境)
用nm工具从系统libc中提取__GI_abort的地址:
nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep __GI_abort
得到地址后,在代码中直接使用常量地址(注意:这种方法不具备可移植性,不同版本、不同架构的glibc中该地址可能完全不同,仅适合调试或固定部署环境)。
另外,如果你的核心需求只是捕获abort的执行时机,也可以直接使用公开的abort符号地址——因为实际执行时abort会跳转到__GI_abort,ptrace捕获到的跳转事件同样能帮你定位到abort的调用流程。
内容的提问来源于stack exchange,提问作者SailorCire
相关产品推荐
相关产品推荐

