0

0

c++如何使用Sanitizers进行代码诊断_c++ UBSan与TSan详解

尼克

尼克

发布时间:2025-12-06 22:41:02

|

197人浏览过

|

来源于php中文网

原创

UBSan和TSan是C++中用于检测未定义行为和数据竞争的实用工具,通过编译时添加-fsanitize=undefined或-thread启用,配合-g和-O1可精准定位问题。

c++如何使用sanitizers进行代码诊断_c++ ubsan与tsan详解

在C++开发中,内存错误、未定义行为和数据竞争是常见但难以排查的问题。Sanitizers(检测工具)是一组编译时和运行时工具,能帮助开发者快速定位这些问题。其中,Undefined Behavior Sanitizer(UBSan)和Thread Sanitizer(TSan)是两个非常实用的工具。下面详细介绍如何使用它们进行代码诊断。

启用Sanitizers的基本方法

Sanitizers由编译器支持,主要在Clang和GCC中可用。使用时需在编译和链接阶段添加特定标志。

以Clang或g++为例:

  • UBSan:编译时加上 -fsanitize=undefined
  • TSan:编译时加上 -fsanitize=thread
  • 同时开启多个检查时,可组合使用,如 -fsanitize=undefined,thread
  • 建议配合 -g 保留调试信息,便于定位源码位置
  • 关闭优化(-O0)有助于更准确地报告问题,但也可用 -O1 或更高

示例编译命令:

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

clang++ -g -O1 -fsanitize=undefined -fsanitize=thread main.cpp -o main

UBSan:检测未定义行为

UBSan用于捕获C++中常见的未定义行为(Undefined Behavior),这类行为在标准中没有规定结果,可能导致程序崩溃或不可预测的行为。

常见可检测的未定义行为包括:

  • 有符号整数溢出(如 int x = INT_MAX + 1;
  • 除以零
  • 空指针解引用
  • 数组越界访问(部分情况)
  • 类型双关违反严格别名规则
  • 移位操作超出位宽(如 x 对于32位int)

示例代码:

int main() {
  int x = 1;
  int y = x   return 0;
}

启用 -fsanitize=undefined 后,运行时会提示类似:

runtime error: left shift of 1 by 31 places cannot be represented in type 'int'

可根据提示快速定位并修复问题。

问问小宇宙
问问小宇宙

问问小宇宙是小宇宙团队出品的播客AI检索工具

下载

TSan:检测数据竞争

TSan专门用于检测多线程程序中的数据竞争(Data Race)。当多个线程并发访问同一内存地址,且至少有一个是写操作,又无同步机制时,就会触发数据竞争。

TSan通过插桩代码记录内存访问和线程同步事件,运行时开销较大(可能慢2-10倍),但能精准报告竞争点。

示例代码:

#include
int global = 0;
void increment() {
  for (int i = 0; i }
int main() {
  std::thread t1(increment);
  std::thread t2(increment);
  t1.join(); t2.join();
  return 0;
}

这段代码中,两个线程同时修改 global 变量,没有加锁。使用 -fsanitize=thread 编译后运行,TSan会输出详细报告,指出哪两处访问导致了竞争,并标注文件名和行号。

修复方法通常是引入互斥锁:

#include
std::mutex mtx;
void increment() {
  for (int i = 0; i     std::lock_guard<:mutex> lock(mtx);
    global++;
  }
}

修复后,TSan不再报错。

使用建议与注意事项

Sanitizers是开发和测试阶段的强大辅助工具,但需注意以下几点:

  • 仅在调试构建中启用,不要用于生产发布版本,因性能开销大
  • TSan要求程序所有线程创建都通过标准方式(如 std::thread),避免直接调用系统API
  • 某些库可能与TSan冲突,可通过 TSAN_OPTIONS 设置屏蔽特定函数
  • UBSan可细分检查项,如只检查整数溢出:-fsanitize=signed-integer-overflow
  • 结合AddressSanitizer(ASan)一起使用效果更佳,全面覆盖内存问题

基本上就这些。合理使用UBSan和TSan,能显著提升C++代码的健壮性和可靠性。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

538

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

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

52

2025.08.29

C++中int的含义
C++中int的含义

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

197

2025.08.29

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

61

2025.12.01

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

22

2025.11.16

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

4874

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

2973

2024.08.14

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

68

2026.01.16

热门下载

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

精品课程

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

共58课时 | 3.8万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.7万人学习

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

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