linux c应用性能与内存泄露问题排查工具

GCC内置的内存检测工具

  在 GCC 中,对 -fsanitize=address(AddressSanitizer, ASan)、-fsanitize=leak(LeakSanitizer, LSan) 和 -fsanitize=memory(MemorySanitizer, MSan) 的支持情况如下:

  1. ​​-fsanitize=address(AddressSanitizer - ASan)​​

    • ​​支持:是​​

    • ​​可用版本:​​ GCC 4.8 开始支持。

    • ​​功能:​​ 检测各种内存错误,包括:

      • 缓冲区溢出(栈、堆、全局变量)

      • 释放后使用 (use-after-free)

      • 返回后使用 (use-after-return)

      • 作用域外使用 (use-after-scope)

      • 双重释放 (double-free)

      • 无效释放 (invalid-free)

    • ​​编译选项:​​ gcc -fsanitize=address -g your_program.c -o your_program

    • 输出示例:

      ==1234==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000003e0 at pc 0x000000349db6

  2. ​​-fsanitize=leak(LeakSanitizer - LSan)​​

    • ​​支持:是​​

    • ​​可用版本:​​ GCC 4.9 开始支持。

    • ​​功能:​​ 专门检测程序结束时仍未释放的内存泄漏。

    • ​​特点:​​

      • 通常作为 ASan 的一部分运行(当使用 -fsanitize=address时,LSan 默认启用)。

      • 也可以独立使用 (-fsanitize=leak),此时它只检测泄漏,不检测其他内存错误(如越界、use-after-free)。独立运行时开销比 ASan 小。

      • 需要程序正常退出(调用 exit(0)或从 main返回)才能运行泄漏检查。强制终止(如 kill -9)不会触发检查。

    • ​​编译选项:​​

      • 独立使用:gcc -fsanitize=leak -g your_program.c -o your_program

      • 作为 ASan 的一部分:gcc -fsanitize=address -g your_program.c -o your_program(LSan 默认启用,可通过环境变量 ASAN_OPTIONS=detect_leaks=0禁用)

      • 输出示例:

        ==1234==ERROR: LeakSanitizer: detected memory leaks
        ==1234==LEAK SUMMARY:
        ==1234== definitely lost: 10 bytes in 1 blocks

    • ​​环境变量 (独立 LSan):​​ LSAN_OPTIONS可用于配置,例如 LSAN_OPTIONS=report_objects=1显示泄漏对象的地址。

  3. ​​-fsanitize=memory(MemorySanitizer - MSan)​​

    • ​​支持:否​​

    • ​​原因:​​ MemorySanitizer 是 LLVM/Clang 项目开发的功能,​​目前 GCC 尚未实现对其的支持​​。

    • ​​功能:​​ MSan 用于检测对未初始化内存的读取。它要求程序中的所有内存在使用前都被明确初始化(例如通过 malloc分配的内存默认是未初始化的)。

    • ​​替代方案:​​ 如果你需要使用 MemorySanitizer,你必须使用 ​​Clang​​ 编译器:clang -fsanitize=memory -g your_program.c -o your_program

    • 输出示例:==1234==ERROR: MemorySanitizer: use-of-uninitialized-value

​​总结:​​

Sanitizer

GCC 命令行选项

GCC 支持

主要功能

备注

AddressSanitizer

-fsanitize=address

​​是​​

内存错误检测 (越界, UAF 等)

GCC >= 4.8

LeakSanitizer

-fsanitize=leak

​​是​​

内存泄漏检测

GCC >= 4.9;常作为 ASan 的一部分运行

MemorySanitizer

-fsanitize=memory

​​否​​

未初始化内存读取检测

​​仅 Clang 支持​​

​​使用注意事项:​​

  • ​​调试信息 (-g):​​ 强烈建议在编译时加上 -g选项生成调试符号。这样 Sanitizer 报告的错误才能包含源代码文件名和行号,极大地帮助定位问题。

  • ​​优化 (-O):​​ Sanitizers 可以在开启优化(如 -O1-O2)的情况下工作,但有时高优化级别可能会影响错误报告的精确位置。调试时通常使用 -O0 -g或 -O1 -g

  • ​​链接:​​ 通常不需要显式链接额外的库(如 -lasan),编译器驱动 (gccg++) 会自动处理。但在某些特殊构建系统中可能需要。

  • ​​运行时开销:​​ Sanitizers 会显著增加程序的内存占用和执行时间(通常 2x 或更多)。它们主要用于​​调试和测试环境​​,​​不应用于生产环境​​。

  • ​​环境变量:​​ 许多 Sanitizer 的行为可以通过环境变量(如 ASAN_OPTIONSLSAN_OPTIONS)进行配置(例如设置退出码、抑制已知问题、控制输出详细程度等)。

 参考

http://www.javashuo.com/article/p-arrgzkvt-m.html  linux下内存泄露查找、BUG调试   https://developer.aliyun.com/article/781575

linux下内存泄露查找、BUG调试 低额外负载  AddressSanitizer  https://www.bynav.com/cn/resource/bywork/healthy-work/70.html?id=35   https://zhuanlan.zhihu.com/p/37515148   https://zhuanlan.zhihu.com/p/534970910

linux应用系统调用sys cpu过高  http://www.kaotop.com/it/819.html  strace命令 – 跟踪系统调用(strace -p PID跟踪指定进程)   https://ywnz.com/linux/strace/

分析调用堆栈的时延  https://zhuanlan.zhihu.com/p/186208907

linux内存回收机制  https://xie.infoq.cn/article/d5143b52ab4233dea90c981ff 

posted @ 2025-09-14 14:05  zhjh256  阅读(40)  评论(0)    收藏  举报