ARM GCC 12下如何确保malloc、free不被链接且调用时构建失败?
一、确保malloc/free不被链接且调用时构建直接失败
要实现调用malloc/free时在构建阶段(优先编译期)直接失败,可采用以下两种互补方案:
1. 编译期强制报错(推荐)
通过重新声明malloc和free函数,并添加__attribute__((error()))属性,只要代码中调用这两个函数,编译阶段就会抛出明确错误并终止构建。将以下代码放入所有源文件都会包含的全局头文件中:
#undef malloc #undef free // 声明时附加错误属性,调用即触发编译报错 void* malloc(size_t) __attribute__((error("禁止调用malloc函数"))); void free(void*) __attribute__((error("禁止调用free函数")));
同时,编译时添加-fno-builtin-malloc -fno-builtin-free选项,禁用GCC内置的malloc/free实现,避免编译器绕过声明优化调用。
2. 链接期兜底阻止
如果编译期防护被绕过,可通过链接器选项彻底阻止malloc/free被链接:
在编译命令中添加链接器参数:
-Wl,--undefined=malloc -Wl,--undefined=free
该选项会强制链接器检查malloc和free是否被定义,若代码中调用了这两个函数但未提供实现,链接阶段会直接报错。
二、类C++ delete的函数阻止机制
C++中通过= delete修饰函数来禁止其调用,ARM GCC为C语言提供了类似的强制阻止能力,核心是利用__attribute__((error()))属性,对需要禁止的函数进行重新声明:
通用示例
若要禁止使用某函数(如strcpy),在全局头文件中添加:
#undef strcpy char* strcpy(char* dest, const char* src) __attribute__((error("禁止使用strcpy,请替换为strncpy")));
只要代码中调用该函数,编译阶段就会抛出指定的错误信息,直接终止构建,效果等同于C++的delete机制。
针对库函数的额外防护
如果目标函数来自系统头文件,可通过编译选项-D提前定义函数名为错误标识,例如:
-Dstrcpy=FORBIDDEN_FUNCTION_strcpy
这样代码中调用strcpy时会被替换为FORBIDDEN_FUNCTION_strcpy,编译时因未定义该标识符报错,但这种方式的错误信息不如__attribute__((error()))直观,仅作为补充方案。
内容的提问来源于stack exchange,提问作者unalignedmemoryaccess

