You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP-IDF下为Address Sanitizer重定义std::free/std::malloc的方法

解决ESP32 C++应用中ASAN适配std::malloc/std::free的编译错误

问题场景

调试ESP32上的C应用内存损坏问题时,使用Erich Styger的tinyK22_FreeRTOS_ASAN代码,其中C语言的malloc()/free()重定义可以正常编译,但因为未处理C标准库的std::malloc和std::free,出现如下编译错误:

In file included from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/stdlib.h:36,
                 from ../../ext/esp-idf/components/newlib/platform_include/assert.h:21,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/sys/reent.h:503,
                 from ../../ext/esp-idf/components/newlib/platform_include/sys/reent.h:17,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/stdio.h:60,
                 from ../../ext/esp-idf/components/esp_common/include/esp_err.h:10,
                 from ../../ext/esp-idf/components/driver/include/driver/gpio.h:10,
                 from ../../include/GfCommon.h:19,
                 from ../../include/GfLogger.h:21,
                 from ../../include/GfInit.h:12,
                 from GfMainApp.cpp:14:
/usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/cstdlib:147:11: error: '::free' has not been declared
   using ::free;
           ^~~~
/usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/cstdlib:151:11: error: '::malloc' has not been declared
   using ::malloc;
           ^~~~~~
In file included from ../../ext/esp-idf/components/newlib/platform_include/assert.h:21,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/sys/reent.h:503,
                 from ../../ext/esp-idf/components/newlib/platform_include/sys/reent.h:17,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/stdio.h:60,
                 from ../../ext/esp-idf/components/esp_common/include/esp_err.h:10,
                 from ../../ext/esp-idf/components/driver/include/driver/gpio.h:10,
                 from ../../include/GfCommon.h:19,
                 from ../../include/GfLogger.h:21,
                 from ../../include/GfInit.h:12,
                 from GfMainApp.cpp:14:
/usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/stdlib.h:61:12: error: 'std::free' has not been declared
 using std::free;
            ^~~~
/usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/stdlib.h:65:12: error: 'std::malloc' has not been declared
 using std::malloc;

尝试用#define std::free直接重定义会报错,自行实现std::free也无效,修改后仍出现如下错误:

In file included from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/stdlib.h:36,
                 from ../../ext/esp-idf/components/newlib/platform_include/assert.h:21,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/sys/reent.h:503,
                 from ../../ext/esp-idf/components/newlib/platform_include/sys/reent.h:17,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/stdio.h:60,
                 from ../../ext/esp-idf/components/esp_common/include/esp_err.h:10,
                 from ../../ext/esp-idf/components/driver/include/driver/gpio.h:10,
                 from ../../include/GfCommon.h:19,
                 from ../../include/GfLogger.h:21,
                 from ../../include/GfInit.h:12,
                 from GfMainApp.cpp:14:
/usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/cstdlib:147:11: error: '::free' has not been declared
   using ::free;
           ^~~~

In file included from ../../ext/esp-idf/components/newlib/platform_include/assert.h:21,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/sys/reent.h:503,
                 from ../../ext/esp-idf/components/newlib/platform_include/sys/reent.h:17,
                 from /usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/stdio.h:60,
                 from ../../ext/esp-idf/components/esp_common/include/esp_err.h:10,
                 from ../../ext/esp-idf/components/driver/include/driver/gpio.h:10,
                 from ../../include/GfCommon.h:19,
                 from ../../include/GfLogger.h:21,
                 from ../../include/GfInit.h:12,
                 from GfMainApp.cpp:14:
/usr/local/espTools/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/8.4.0/stdlib.h:61:12: error: 'std::free' has not been declared
 using std::free;
            ^~~~

正确实现方案

核心是先保留原始内存函数的声明,再替换为ASAN版本,同时为C++标准库提供std命名空间下的实现,避免编译器找不到符号:

  1. 调整头文件包含顺序:确保ASAN的重定义代码在所有C/C++标准库头文件之前被包含。
  2. 保存原始函数指针:避免递归调用,同时确保原始内存函数能被访问。
  3. 实现std命名空间的内存函数:为C++标准库提供对应的符号。

具体代码示例:

// 先包含标准库头文件,获取原始malloc/free的声明
#include <stdlib.h>

#if McuASAN_CONFIG_IS_ENABLED && McuASAN_CONFIG_CHECK_MALLOC_FREE
// 声明原始内存函数,用于在ASAN版本中调用
extern "C" {
void* __real_malloc(size_t size);
void __real_free(void* ptr);
}

// 重定义全局malloc/free为ASAN版本
#define malloc __asan_malloc
#define free __asan_free

// ASAN版本的malloc实现,添加内存检查逻辑
void* __asan_malloc(size_t size) {
    // 这里添加你的ASAN内存分配检查逻辑(比如记录分配地址、大小等)
    void* ptr = __real_malloc(size);
    // 示例:标记内存块为已分配
    // McuASAN_RecordAllocation(ptr, size);
    return ptr;
}

// ASAN版本的free实现,添加内存检查逻辑
void __asan_free(void* ptr) {
    if (ptr == NULL) {
        return;
    }
    // 这里添加你的ASAN内存释放检查逻辑(比如检查是否重复释放、越界等)
    // McuASAN_CheckFree(ptr);
    __real_free(ptr);
}

#ifdef __cplusplus
namespace std {
    // 为C++标准库提供std::malloc,调用ASAN版本
    inline void* malloc(size_t size) {
        return __asan_malloc(size);
    }

    // 为C++标准库提供std::free,调用ASAN版本
    inline void free(void* ptr) {
        __asan_free(ptr);
    }
}
#endif
#endif

额外注意事项

  • 在ESP-IDF环境中,若使用newlib的重入版本(_malloc_r/_free_r),需要同步处理这些函数的重定义,确保覆盖所有内存分配路径。
  • 确保ASAN的相关检查函数(如McuASAN_RecordAllocation、McuASAN_CheckFree)已正确实现,避免未定义引用错误。

内容的提问来源于stack exchange,提问作者Danny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:40:40