检测内存问题

(2 mins to read)

AddressSanitizer

相比Valgrind快,主要就是替换了程序中的malloc()free()

在编译时添加以下选项为编译参数(CFLAGS/CXXFLAGS)以及链接参数(LDFLAGS):

  • -fsanitize=address:内存错误(通过替换malloc,在每次申请内存块的前后都设置guard)
  • -fsanitize=leak:内存泄露
  • -fsanitize=thread:多线程竞争
  • -fsanitize=undefined:未定义操作
  • -fsanitize=memory:未初始化内存读取(与address冲突)
  • -fno-sanitize-recover:在检测到第一个错误后就退出,否则会继续运行(在指定检测undefined时可选启用)
  • -fsanitize=pointer-compare:确保没有不同对象的指针比较(需要结合address使用,且不能与thread一起使用)

可以使用__attribute__((no_sanitize_address)跳过分析某个函数。

Valgrind Memcheck

valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full ./prog

valgrind在检测BPF CO-RE程序时会出现FATAL: unhandled eBPF command 22的问题。

内存踩踏

Memory stomp:对不属于你的内存进行读写。

有时候特指访问越界,但恰好无意识地操作到了其它的合法地址,如另一个数据结构。

一段经典代码:

1
2
3
4
5
6
7
8
9
include <stdio.h>
int main()
{
int array[10],i;
for (i = 0; i <=10 ; i++)
{
array[i]=0; /*code should never terminate*/
}
}

有可能$i$恰好在array的下一个位置,每次array[10]=0等价于i=0,从而导致了死循环。