Ubuntu下C++编译链接阶段libasan.so.6警告的解决方法咨询
解决链接阶段重复tmpnam/tempnam警告的方案
程序员视角
- 定位调用来源:使用
nm工具扫描依赖的第三方库,找出间接调用的源头:
若第三方库是可修改的(比如自研或开源可定制),直接将nm -D /path/to/your/thirdparty/library.so | grep -E 'tmpnam|tempnam'tmpnam/tempnam替换为安全的mkstemp;若是开源库,优先升级到已修复该问题的最新版本。 - 抑制重复警告:如果暂时无法修改依赖,可在编译链接时添加参数让链接器只显示一次警告,避免刷屏:
若确认风险可控,也可关闭所有链接警告(谨慎使用):g++ your_code.cpp -o your_program -fsanitize=address -Wl,--warn-onceg++ your_code.cpp -o your_program -fsanitize=address -Wl,-w - 符号重定义(谨慎使用):如果第三方库是静态链接的,可自行实现
tmpnam/tempnam函数转调用mkstemp,编译时通过链接器参数替换原符号:
编译时加上参数:#include <cstdio> #include <cstdlib> #include <unistd.h> // 声明原函数 char* __real_tmpnam(char*); char* __real_tempnam(const char*, const char*); char* __wrap_tmpnam(char* s) { char buf[] = "/tmp/secure_temp.XXXXXX"; int fd = mkstemp(buf); if (fd == -1) return nullptr; close(fd); if (s) { snprintf(s, L_tmpnam, "%s", buf); return s; } return strdup(buf); } char* __wrap_tempnam(const char* dir, const char* prefix) { char buf[256]; snprintf(buf, sizeof(buf), "%s/%sXXXXXX", dir ? dir : "/tmp", prefix ? prefix : "temp"); int fd = mkstemp(buf); if (fd == -1) return nullptr; close(fd); return strdup(buf); }g++ your_code.cpp wrap_temp_func.cpp -o your_program -fsanitize=address -Wl,--wrap=tmpnam -Wl,--wrap=tempnam
系统管理员视角
- 更新系统库:通过包管理器更新
libasan6,官方可能已修复该警告问题:sudo apt update && sudo apt upgrade libasan6 - 编译替换最新libasan:若官方源无更新版本,可从gcc源码编译对应版本的
libasan,替换系统中的库文件(操作前务必备份原库/usr/lib/x86_64-linux-gnu/libasan.so.6):- 下载对应版本的gcc源码(如gcc 11.4.0)
- 编译时指定
--enable-libsanitizer选项 - 将编译生成的
libasan.so.6复制到系统库目录并更新符号链接
- 全局配置编译选项:为所有项目统一添加警告抑制参数,修改
/etc/profile或用户的~/.bashrc,添加:
执行export LDFLAGS="-Wl,--warn-once"source /etc/profile或重启终端后,所有编译链接操作都会自动应用该参数,避免重复警告刷屏。
内容的提问来源于stack exchange,提问作者Kemin Zhou
相关产品推荐
相关产品推荐

