如何规避GCC编译musl编译器时的‘attempt to use poisoned calloc’错误?
解决musl环境下编译GCC 8.3.0时calloc被poisoned的错误
这个错误的核心原因是:GCC在编译自身前端代码(比如brig模块)时,会通过#pragma GCC poison calloc临时禁用calloc函数,防止代码误用;但musl的sched.h头文件直接声明了calloc,还在CPU_ALLOC宏里调用了它,两者的规则冲突导致编译报错。
下面是两种可行的解决方法:
方法一:修改musl的sched.h头文件
直接调整musl头文件的条件编译逻辑,避开GCC编译自身时的poison检测:
- 打开交叉编译器的musl头文件:
/usr/local/x86_64-cros-linux-musl/include/sched.h - 找到第76行的
void *calloc(size_t, size_t);,替换为:#ifndef __POISONED_CALLOC void *calloc(size_t, size_t); #endif - 找到第116行的
#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n))),替换为:
这里用#ifndef __POISONED_CALLOC #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n))) #else #define CPU_ALLOC(n) ((cpu_set_t *)malloc(CPU_ALLOC_SIZE(n))) #endifmalloc临时替代calloc,因为编译GCC自身时CPU_ALLOC宏大概率不会被实际调用,即使调用,后续手动内存清零也能满足需求(实际编译GCC前端代码时基本不会用到这个宏)。
方法二:调整GCC编译时的宏定义
在编译GCC的过程中,给brig相关的编译单元添加宏定义,取消calloc的poison标记:
- 进入GCC的构建目录,定位到
gcc/brig/Makefile - 在
CFLAGS或CXXFLAGS中添加-U__POISONED_CALLOC选项,比如执行:sed -i 's/CFLAGS = /CFLAGS = -U__POISONED_CALLOC /' gcc/brig/Makefile - 重新执行编译命令即可。
额外提示
如果你已经应用了musl的GCC补丁,可能需要检查补丁是否覆盖了这个头文件冲突问题——部分旧补丁可能没有处理GCC 8.3.0的brig模块头文件依赖场景,所以手动调整上述内容就能解决问题。
内容的提问来源于stack exchange,提问作者S.S. Anne
相关产品推荐
相关产品推荐

