Memory/Address 消毒剂与 Valgrind
Memory/Address Sanitizer vs Valgrind
我想要一些工具来诊断释放后使用错误和未初始化的错误。我正在考虑 Sanitizer(Memory and/or Address) 和 Valgrind。但是我对它们的优点和缺点知之甚少。谁能说出Sanitizer和Valgrind的主要特点、区别和pros/cons?
编辑:我发现了一些比较,例如:Valgrind 使用 DBI(动态二进制检测)而 Sanitizer 使用 CTI(编译时检测)。 Valgrind 使程序慢得多(20 倍)是否 Sanitizer 运行速度比 Valgrind 快得多(2 倍)。如果有人能给我一些更重要的考虑点,那将是一个很大的帮助。
我想你会发现这个 wiki 有用。
TLDR 消毒剂的主要优点是
- CPU 开销小得多(Lsan 实际上是免费的,UBsan 是 1.25 倍,Asan 和 Msan 对于计算密集型任务是 2-4 倍,对于 GUI 是 1.05-1.1 倍,Tsan 是 5-15 倍)
- 更广泛的 class 检测到的错误(堆栈和全局溢出,使用后 return)
- 完全支持多线程应用程序(Valgrind 对多线程的支持是个笑话)
- 内存开销小得多(Asan 高达 2 倍,Msan 高达 3 倍,Tsan 高达 10 倍,这比 Valgrind 好得多)
缺点是
- 更复杂的集成(你需要教你的构建系统理解 Asan,有时在 Asan 中解决 limitations/bugs,你还需要使用相对较新的编译器)
- MemorySanitizer 目前还不是很容易使用,因为它需要重建 Msan 下的所有依赖项(包括所有标准库,例如 libstdc++);这意味着临时用户只能使用 Valgrind 来检测未初始化的错误
- 消毒剂通常不能相互组合(唯一受支持的组合是 Asan+UBsan+Lsan),这意味着您必须进行单独的 QA 运行才能捕获所有类型的错误
一个很大的区别是 LLVM-included memory and thread 消毒剂隐式映射了大量的地址 space(例如,通过调用 mmap(X, Y, 0, MAP_NORESERVE|MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, -1, 0)
跨越 TB 的地址 space 在 x86_64 环境中)。即使他们不一定分配该内存,映射也会对限制性环境造成严重破坏(例如,ulimit
值具有合理设置的环境)。
我想要一些工具来诊断释放后使用错误和未初始化的错误。我正在考虑 Sanitizer(Memory and/or Address) 和 Valgrind。但是我对它们的优点和缺点知之甚少。谁能说出Sanitizer和Valgrind的主要特点、区别和pros/cons?
编辑:我发现了一些比较,例如:Valgrind 使用 DBI(动态二进制检测)而 Sanitizer 使用 CTI(编译时检测)。 Valgrind 使程序慢得多(20 倍)是否 Sanitizer 运行速度比 Valgrind 快得多(2 倍)。如果有人能给我一些更重要的考虑点,那将是一个很大的帮助。
我想你会发现这个 wiki 有用。
TLDR 消毒剂的主要优点是
- CPU 开销小得多(Lsan 实际上是免费的,UBsan 是 1.25 倍,Asan 和 Msan 对于计算密集型任务是 2-4 倍,对于 GUI 是 1.05-1.1 倍,Tsan 是 5-15 倍)
- 更广泛的 class 检测到的错误(堆栈和全局溢出,使用后 return)
- 完全支持多线程应用程序(Valgrind 对多线程的支持是个笑话)
- 内存开销小得多(Asan 高达 2 倍,Msan 高达 3 倍,Tsan 高达 10 倍,这比 Valgrind 好得多)
缺点是
- 更复杂的集成(你需要教你的构建系统理解 Asan,有时在 Asan 中解决 limitations/bugs,你还需要使用相对较新的编译器)
- MemorySanitizer 目前还不是很容易使用,因为它需要重建 Msan 下的所有依赖项(包括所有标准库,例如 libstdc++);这意味着临时用户只能使用 Valgrind 来检测未初始化的错误
- 消毒剂通常不能相互组合(唯一受支持的组合是 Asan+UBsan+Lsan),这意味着您必须进行单独的 QA 运行才能捕获所有类型的错误
一个很大的区别是 LLVM-included memory and thread 消毒剂隐式映射了大量的地址 space(例如,通过调用 mmap(X, Y, 0, MAP_NORESERVE|MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, -1, 0)
跨越 TB 的地址 space 在 x86_64 环境中)。即使他们不一定分配该内存,映射也会对限制性环境造成严重破坏(例如,ulimit
值具有合理设置的环境)。