工具
valgrind 是一个强大的内存调试和性能分析工具,它的不同子工具用于不同的分析目的。--memcheck
和 --massif
是其中两个常用的工具。
ASAN(AddressSanitizer) 和 TSAN(ThreadSanitizer) 都是由现代编译器(如 Clang 和 GCC)提供的 运行时检测工具,用于帮助开发者在开发阶段发现内存错误和线程问题。
- Clang:全面支持 ASAN 和 TSAN
- GCC:也支持,但 TSAN 的支持略逊于 Clang
博客:How to get a core dump for a segfault on Linux
Memcheck:内存错误检查工具
官方文档:4. Memcheck: a memory error detector
- 用途:检测内存相关的错误,如内存泄漏、越界访问、未初始化内存读取等。
- 适用场景:调试程序中的内存错误,确保程序的内存使用是安全的。
- 输出内容:
- 哪些内存没有释放(内存泄漏)
- 哪些内存被非法访问(越界、未初始化等)
- 哪些内存访问是未定义行为
- 常用命令:
1 | valgrind --tool=memcheck ./your_program |
Massif:堆内存使用分析工具
官方文档:9. Massif: a heap profiler
- 用途:分析程序在运行过程中堆内存的使用情况,帮助优化内存占用。
- 适用场景:性能分析,找出内存占用高的代码路径或数据结构。
- 输出内容:
- 堆内存使用随时间的变化(快照):需用
ms_print
或 PostScript Viewer 查看 - 哪些函数或调用路径分配了最多的内存
- 常用命令:
- 堆内存使用随时间的变化(快照):需用
1 | valgrind --tool=massif ./your_program |
🆚 Memcheck vs Massif 对比总结
特性 | --memcheck |
--massif |
---|---|---|
工具类型 | 内存错误检查工具 | 堆内存使用分析工具 |
主要用途 | 检查内存泄漏、越界访问、未初始化读取等 | 分析堆内存使用趋势和峰值 |
检测内存泄漏 | ✅ | ❌(不直接检测) |
分析内存增长趋势 | ❌ | ✅ |
输出格式 | 错误报告(文本) | 内存快照(需用 ms_print 查看) |
性能开销 | 高(运行速度变慢) | 中等 |
ThreadSanitizer(TSAN)
- 用途:检测多线程程序中的 数据竞争(data race) 和其他线程同步问题。
- 适用场景:并发程序调试,尤其是当多个线程访问共享变量时。
- 检测内容:
- 数据竞争(两个线程同时访问同一变量,且至少一个是写操作)
- 锁使用错误(死锁、双重解锁等)
- 启用方式(Clang/GCC):
1 | clang -fsanitize=thread -g your_program.c -o your_program |
AddressSanitizer(ASAN)
- 用途:检测内存访问错误。
- 适用场景:单线程或多线程程序中调试内存问题。
- 检测内容:
- 越界访问(stack/heap/global)
- use-after-free(释放后使用)
- 内存泄漏(可选)
- use-after-scope(作用域结束后使用局部变量)
- 启用方式:
1 | clang -fsanitize=address -g your_program.c -o your_program |
🆚 TSAN vs ASAN 对比总结
特性 | TSAN(ThreadSanitizer) | ASAN(AddressSanitizer) |
---|---|---|
检测目标 | 多线程数据竞争 | 内存访问错误 |
是否支持多线程 | ✅(专为多线程设计) | ✅(支持,但不检测数据竞争) |
性能开销 | 较高(10x~40x) | 中等(2x~3x) |
内存开销 | 中等 | 较高(增加约2倍内存使用) |
是否检测内存泄漏 | ❌(不检测) | ✅(可选开启) |
是否检测数据竞争 | ✅ | ❌ |
🆚 Memcheck vs Massif vs TSAN vs ASAN 对比总结
工具名称 | 类型 | 主要用途 | 检测内容 | 是否支持多线程 | 性能开销 | 内存开销 | 是否检测内存泄漏 | 是否检测数据竞争 |
---|---|---|---|---|---|---|---|---|
Memcheck | Valgrind 工具 | 内存错误检测 | 内存泄漏、越界访问、未初始化读取、非法释放等 | ✅(有限支持) | 高(10x+) | 高 | ✅ | ❌ |
Massif | Valgrind 工具 | 堆内存使用分析 | 堆内存分配趋势、内存峰值、调用路径分析 | ✅ | 中等 | 中等 | ❌ | ❌ |
ASAN | 编译器工具 | 内存访问错误检测 | 越界访问、use-after-free、use-after-scope、内存泄漏(可选) | ✅ | 中等(2x~3x) | 高(约2倍) | ✅(可选) | ❌ |
TSAN | 编译器工具 | 多线程数据竞争检测 | 数据竞争、死锁、错误的锁使用等 | ✅(强支持) | 高(5x~40x) | 中等 | ❌ | ✅ |
UBSan (Unifined Behavior Sanitizer)
Sanitizer | 检测内容 | Google 贡献 |
---|---|---|
ASAN | 内存访问错误 | ✅ 是 |
UBSan | 未定义行为 | ✅ 是 |
TSAN | 数据竞争 | ✅ 是 |
MSAN | 未初始化内存使用 | ✅ 是 |