¶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 | include <stdio.h> |
有可能$i$恰好在array的下一个位置,每次array[10]=0
等价于i=0
,从而导致了死循环。