重新定义/覆盖 ESP-IDF 上地址清理器的 std::free / std::malloc



我正在 ESP32 上运行的 C++ 应用程序上调试一个困难的内存损坏问题,并尝试使用 Erich Styger 的 ASAN tinyK22_FreeRTOS_ASAN代码。

他对 C 的重新定义malloc()free()编译,但我得到编译错误,因为std::mallocstd::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;

对于 C,代码使用#define来重新定义free()#define std::free xxx抛出错误std::free因为"不是标识符"。我试图重新定义std::free如下所示,但没有奏效。

[编辑"它不起作用"表示打印了与上述相同的错误消息 ]

#if McuASAN_CONFIG_IS_ENABLED && McuASAN_CONFIG_CHECK_MALLOC_FREE
/* replace malloc and free calls */
#define malloc   __asan_malloc
#define free     __asan_free
#endif
#ifdef __cplusplus
namespace std
{
void free(void *ptr)
{
if (ptr != 0)
{
free(ptr);
}
}
}
#endif

正确的方法是什么?

编辑二

尝试@Ross的建议会给出以下错误:

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;
^~~~

你的代码看起来不错,但请记住,你写free的任何地方都会因为#define free ...而被重写为__asan_free

以下版本通过在std命名空间中显式定义__asan_free来避免与预处理器重写内容的任何混淆,并通过在::__asan_free上使用显式全局命名空间限定符修复了委托给符号的 C 版本的问题。

#if McuASAN_CONFIG_IS_ENABLED && McuASAN_CONFIG_CHECK_MALLOC_FREE
/* replace malloc and free calls */
#define malloc   __asan_malloc
#define free     __asan_free
#endif
#ifdef __cplusplus
// forward declare the global "C" versions:
extern "C" void __asan_free(void *ptr); 
// TODO: forward declare __asan_malloc too
namespace std
{
void __asan_free(void *ptr) // this will get called anywhere that writes `std::free`
{
if (ptr != 0)
{
::__asan_free(ptr); // call global "C" version
}
}
// TODO: also __asan_malloc
}
#endif

如果您更喜欢使用/不使用ASAN的东西,您可以保留当前代码,只需将调用更改为全局免费以::free。您还需要确保__asan_malloc__asan_free(以及不使用 ASAN 时的mallocfree)的全局命名空间版本具有可见的extern "C"声明。

#if McuASAN_CONFIG_IS_ENABLED && McuASAN_CONFIG_CHECK_MALLOC_FREE
/* replace malloc and free calls */
#define malloc   __asan_malloc
#define free     __asan_free
#endif
#ifdef __cplusplus
namespace std
{
void free(void *ptr) // NB: rewritten to __asan_free when ASAN enabled
{
if (ptr != 0)
{
::free(ptr); // call global "C" version
// ^^^ NB rewritten to ::__asan_free  when ASAN enabled
}
}
// TODO: also malloc
}
#endif

最新更新