为什么地址清理器没有检测到这个简单的内存泄漏?
Why is address sanitizer not detecting this simple memory leak?
有没有人知道为什么地址清理器没有标记这个非常明显的内存泄漏
class A {
public:
A() = default;
};
TEST_F(LibrdfSerializerTests, Test) {
A* a = new A;
}
在 cmake 中添加了以下内容:
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
您可以在执行二进制文件时尝试使用 ASAN_OPTIONS=detect_leaks=1
来检测泄漏。使用文档中的示例
❯ cat leak.c
#include <stdlib.h>
void *p;
int main() {
p = malloc(7);
p = 0; // The memory is leaked here.
return 0;
}
编译程序
clang -fsanitize=address -g leak.c
然后执行如下:
ASAN_OPTIONS=detect_leaks=1 ./a.out
输出:
=================================================================
==63987==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 7 byte(s) in 1 object(s) allocated from:
#0 0x1034c109d in wrap_malloc+0x9d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4609d)
#1 0x103477ef8 in main leak.c:4
#2 0x7fff6b30fcc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)
SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s).
CPP 相同
❯ cat memory-leak.cpp
#include <cstdlib>
#include <cstdio>
class A {
public:
A() = default;
};
int main() {
char const* asanOpt = std::getenv("ASAN_OPTIONS");
std::printf("%s\n", asanOpt);
A* a = new A;
return 0;
}
编译它
clang++ -g memory-leak.cpp -fsanitize=address
执行二进制文件时,使用选项启用泄漏检测
ASAN_OPTIONS=detect_leaks=1 ./a.out
输出:
detect_leaks=1
=================================================================
==69309==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1 byte(s) in 1 object(s) allocated from:
#0 0x109ea556d in wrap__Znwm+0x7d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5256d)
#1 0x109e4bf48 in main memory-leak.cpp:7
#2 0x7fff6b30fcc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)
SUMMARY: AddressSanitizer: 1 byte(s) leaked in 1 allocation(s).
测试于:
MacOS 10.15
有叮当声
clang version 10.0.1
Target: x86_64-apple-darwin19.6.0
Thread model: posix
有没有人知道为什么地址清理器没有标记这个非常明显的内存泄漏
class A {
public:
A() = default;
};
TEST_F(LibrdfSerializerTests, Test) {
A* a = new A;
}
在 cmake 中添加了以下内容:
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
您可以在执行二进制文件时尝试使用 ASAN_OPTIONS=detect_leaks=1
来检测泄漏。使用文档中的示例
❯ cat leak.c
#include <stdlib.h>
void *p;
int main() {
p = malloc(7);
p = 0; // The memory is leaked here.
return 0;
}
编译程序
clang -fsanitize=address -g leak.c
然后执行如下:
ASAN_OPTIONS=detect_leaks=1 ./a.out
输出:
=================================================================
==63987==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 7 byte(s) in 1 object(s) allocated from:
#0 0x1034c109d in wrap_malloc+0x9d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4609d)
#1 0x103477ef8 in main leak.c:4
#2 0x7fff6b30fcc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)
SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s).
CPP 相同
❯ cat memory-leak.cpp
#include <cstdlib>
#include <cstdio>
class A {
public:
A() = default;
};
int main() {
char const* asanOpt = std::getenv("ASAN_OPTIONS");
std::printf("%s\n", asanOpt);
A* a = new A;
return 0;
}
编译它
clang++ -g memory-leak.cpp -fsanitize=address
执行二进制文件时,使用选项启用泄漏检测
ASAN_OPTIONS=detect_leaks=1 ./a.out
输出:
detect_leaks=1
=================================================================
==69309==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1 byte(s) in 1 object(s) allocated from:
#0 0x109ea556d in wrap__Znwm+0x7d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5256d)
#1 0x109e4bf48 in main memory-leak.cpp:7
#2 0x7fff6b30fcc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)
SUMMARY: AddressSanitizer: 1 byte(s) leaked in 1 allocation(s).
测试于:
MacOS 10.15
有叮当声
clang version 10.0.1
Target: x86_64-apple-darwin19.6.0
Thread model: posix