C语言自定义mkdirhier函数未被调用的排查求助
排查与解决思路
1. 确认系统库中是否存在mkdirhier函数
- 直接检查系统标准库及依赖库:
- 执行
nm -D /lib64/libc.so.6 | grep mkdirhier(32位系统替换为/lib/libc.so.6),查看libc中是否有该函数。 - 用
ldd 你的可执行文件名 | awk '{print $3}' | grep -v '^$' | xargs nm -D | grep mkdirhier,遍历可执行文件的所有依赖系统库,查找同名函数。 - 执行
man mkdirhier,确认系统是否自带该工具函数的文档。
- 执行
2. 调整编译链接顺序
- 检查Makefile或编译脚本,确保自定义
mkdirhier所在的目标文件(.o)或静态库(.a)在系统库之前链接。链接器会优先使用先找到的符号,若系统库在前,会优先绑定系统版本。 - 示例调整后的编译命令:
gcc main.c your_mkdirhier.o -o app(将自定义代码的.o文件放在编译参数靠前位置)
3. 排查符号覆盖与声明问题
- 检查代码中是否引入了包含
mkdirhier系统声明的头文件(如部分系统的工具类头文件),可通过gcc -E 你的源文件.c | grep mkdirhier查看预处理后的代码,确认是否存在宏替换或系统声明覆盖。 - 若发现系统宏定义覆盖,在自定义函数的声明和调用位置前添加
#undef mkdirhier,取消宏定义后重新声明自定义函数:#undef mkdirhier extern int mkdirhier(char * path, mode_t mode, uid_t uid, gid_t gid); - 若编译时使用了
-fvisibility=hidden等符号隐藏选项,在自定义函数前添加__attribute__((visibility("default")))强制暴露符号:__attribute__((visibility("default"))) int mkdirhier(char * path, mode_t mode, uid_t uid, gid_t gid) { printf("TEMP_DEBUG: Inside function mkdirhier"); <source code> }
4. 链接时强制绑定自定义符号
- 使用
-u mkdirhier编译选项,强制链接器优先解析该符号,确保先找到自定义版本:gcc -u mkdirhier main.c your_mkdirhier.o -o app - 或添加
-Wl,-Bsymbolic链接选项,让链接器优先使用当前二进制内的符号定义,而非系统库的同名符号:gcc main.c your_mkdirhier.o -o app -Wl,-Bsymbolic
5. GDB深度验证
- 在GDB中执行
info functions mkdirhier,查看所有匹配的函数地址,区分自定义版本与系统版本。 - 执行
set stop-on-solib-events 1,让GDB在加载共享库时暂停,在加载自定义代码所在的库/目标文件后,立即设置mkdirhier断点,验证是否能命中自定义函数。 - 程序运行触发调用时,执行
bt查看调用栈,确认实际调用的函数地址归属。
内容的提问来源于stack exchange,提问作者Amit
相关产品推荐
相关产品推荐

