0

0

c++怎么用asan, tsan, ubsan进行运行时检查_C++三大运行时检测工具使用指南

穿越時空

穿越時空

发布时间:2025-11-05 23:57:02

|

603人浏览过

|

来源于php中文网

原创

使用ASan、TSan和UBSan可高效检测C++中的内存错误、数据竞争和未定义行为;2. ASan通过-g -O1 -fsanitize=address编译选项启用,用于捕获内存越界、释放后使用等问题。

c++怎么用asan, tsan, ubsan进行运行时检查_c++三大运行时检测工具使用指南

在C++开发中,内存错误、数据竞争和未定义行为是常见但难以调试的问题。AddressSanitizer(ASan)、ThreadSanitizer(TSan)和UndefinedBehaviorSanitizer(UBSan)是Clang和GCC内置的强大运行时检测工具,能帮助开发者快速定位这些问题。下面介绍如何在实际项目中使用这三大工具。

AddressSanitizer(ASan):检测内存错误

ASan用于捕获内存越界访问、使用已释放内存、/堆缓冲区溢出等问题。

使用方法:

-fsanitize=address 启用ASan,在编译和链接时都需加上该标志。

示例编译命令:

立即学习C++免费学习笔记(深入)”;

g++ -g -O1 -fsanitize=address -fno-omit-frame-pointer your_code.cpp -o your_program
  • -g:保留调试信息,便于定位错误位置
  • -O1:建议至少开启O1优化,某些情况下O0可能影响检测精度
  • -fno-omit-frame-pointer:保持帧指针,提升堆栈回溯质量

常见检测问题:

  • 堆缓冲区溢出
  • 栈缓冲区溢出
  • 全局缓冲区溢出
  • 释放后使用(use-after-free)
  • 双重释放

运行程序后,ASan会打印详细错误信息,包括错误类型、调用栈和源码行号。

ThreadSanitizer(TSan):检测数据竞争

TSan用于发现多线程程序中的数据竞争问题,对调试并发bug非常有效。

使用方法:

-fsanitize=thread 启用TSan。

编译命令示例:

g++ -g -O1 -fsanitize=thread -fno-omit-frame-pointer -pthread your_threaded_code.cpp -o your_program
  • 必须链接pthread(或多线程支持)
  • TSan开销较大,建议仅在测试环境使用

TSan能检测:

Adrenaline
Adrenaline

软件调试助手,识别和修复代码中错误

下载
  • 不同线程对同一内存的非原子访问,且至少一个是写操作
  • 锁的不正确使用导致的竞争
  • 条件变量使用不当引发的问题

输出会显示两个竞争线程的访问路径和加锁状态,帮助快速分析竞争根源。

UndefinedBehaviorSanitizer(UBSan):捕获未定义行为

UBSan检查C++中各类未定义行为,如整数溢出、空指针解引用、类型双关等。

使用方法:

-fsanitize=undefined 启用UBSan。

编译命令示例:

g++ -g -O1 -fsanitize=undefined your_code.cpp -o your_program
  • 也可使用更细粒度选项,如 -fsanitize=signed-integer-overflow 只检测有符号整数溢出
  • 部分检查可在-O2以上生效

典型检测项:

  • 有符号整数溢出
  • 除以零
  • 空指针解引用
  • 动态类型转换失败(via dynamic_cast)
  • 数组越界(部分情况)

UBSan通常性能开销较小,可考虑集成到日常构建流程中。

组合使用与注意事项

ASan、TSan、UBSan不能同时启用。例如ASan和TSan互斥,因为它们都重写了内存访问逻辑。

推荐策略:

  • 日常调试用ASan + UBSan
  • 多线程专项测试用TSan
  • 持续集成中分任务运行不同Sanitizer

其他提示:

  • 确保使用较新版本的GCC(≥7)或Clang(≥5)以获得完整支持
  • 配合 -g 编译选项获取精确源码位置
  • 避免在生产环境长期开启,因性能损耗明显
  • 可设置环境变量控制行为,如 ASAN_OPTIONS=detect_container_overflow=1

基本上就这些。合理使用这三个工具,能极大提升C++代码的健壮性,把很多隐蔽bug消灭在早期阶段。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

574

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

574

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

482

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

5

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

11

2026.01.21

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

25

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 7.5万人学习

C 教程
C 教程

共75课时 | 4.2万人学习

C++教程
C++教程

共115课时 | 13.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号