facebookresearch/CUTracer
GitHub: facebookresearch/CUTracer
基于 NVBit 的 CUDA 动态二进制插桩工具,提供指令直方图分析、死锁检测和数据竞争检测能力。
Stars: 35 | Forks: 6
# CUTracer
CUTracer 是一个基于 [NVBit](https://github.com/NVlabs/NVBit) 的 CUDA 二进制插桩工具。它将轻量级的数据收集(插桩)与主机端处理(分析)完全分离。典型的工作流包括按 warp 统计的指令直方图(通过 GPU 时钟读取分隔)以及 kernel 挂起检测。
## 功能
- 基于 NVBit,通过 `CUDA_INJECTION64_PATH` 进行运行时附加(无需重新构建应用程序)
- 多种插桩模式:仅操作码、寄存器追踪、内存追踪、随机延迟
- 内置分析功能:
- 指令直方图(用于 Proton/Triton 工作流)
- 死锁/挂起检测
- 数据竞争检测
- 支持 CUDA Graph 和流捕获流程
- 确定性的 kernel 日志文件命名和 CSV 输出
## 环境要求
所有要求与 NVBit 保持一致。
独特要求:
- **libzstd**:追踪压缩所需
## 安装
1. 克隆仓库:
```
git clone git@github.com:facebookresearch/CUTracer.git
cd CUTracer
```
2. 安装系统依赖(用于独立构建的 libzstd 静态库):
```
# Ubuntu/Debian
# 在大多数 Ubuntu/Debian 系统上,libzstd-dev 同时提供了 shared 和 static libs (libzstd.a)。
# 你可以使用以下命令进行验证:dpkg -L libzstd-dev | grep 'libzstd.a'
# 如果你的发行版没有在 libzstd-dev 中提供 static library,你可能需要
# 从源码构建 zstd 或安装特定于发行版的 static libzstd 包。
sudo apt-get install libzstd-dev
# CentOS/RHEL/Fedora (用于 portable builds 的 static library)
sudo dnf install libzstd-static
# 如果 static library 不可用,构建将回退到 dynamic linking
# 并显示警告。生成的 binary 将不是 self-contained 的。
```
3. 下载第三方依赖:
```
./install_third_party.sh
```
这将下载:
- NVBit (NVIDIA 二进制插桩工具)
- nlohmann/json (C++ JSON 库)
4. 构建工具:
```
make -j$(nproc)
```
## 快速入门
使用 CUTracer 运行您的 CUDA 应用程序(示例:无插桩):
```
CUDA_INJECTION64_PATH=~/CUTracer/lib/cutracer.so \
./your_app
```
## 配置(环境变量)
- `CUTRACER_INSTRUMENT`:逗号分隔的模式:`opcode_only`、`reg_trace`、`mem_trace`、`random_delay`
- `CUTRACER_ANALYSIS`:逗号分隔的分析:`proton_instr_histogram`、`deadlock_detection`、`random_delay`
- 启用 `proton_instr_histogram` 会自动启用 `opcode_only`
- 启用 `deadlock_detection` 会自动启用 `reg_trace`
- 启用 `random_delay` 需要设置 `CUTRACER_DELAY_NS`
- `KERNEL_FILTERS`:逗号分隔的子字符串,用于匹配未修饰或修饰过的 kernel 名称
- `INSTR_BEGIN`、`INSTR_END`:插桩期间的静态指令索引门控
- `TOOL_VERBOSE`:0/1/2
- `TRACE_FORMAT_NDJSON`:追踪输出格式
- **1**(默认):NDJSON+Zstd 压缩(`.ndjson.zst`,约 12 倍压缩率,节省 92% 空间)
- 0:纯文本(`.log`,传统格式,较冗长)
- 2:NDJSON 未压缩(`.ndjson`,用于调试)
- `CUTRACER_ZSTD_LEVEL`:Zstd 压缩级别(1-22,默认为 22)
- 较低的值 (1-3):压缩速度更快,输出稍大
- 较高的值 (19-22):最大程度压缩,速度较慢但输出最小
- 默认值 22 提供最大程度的压缩以获得最小的输出
- `CUTRACER_DELAY_NS`:用于竞争检测的固定延迟值(以纳秒为单位)(`random_delay` 分析必需)
- `CUTRACER_DELAY_DUMP_PATH`:延迟配置 JSON 文件的输出路径(用于记录插桩模式)
- `CUTRACER_DELAY_LOAD_PATH`:延迟配置 JSON 文件的输入路径(用于重放模式 - 确定性复现)
- `CUTRACER_OUTPUT_DIR`:所有 CUTracer 文件(追踪文件和日志文件)的输出目录。默认为当前目录。该目录必须存在且可写
注意:该工具设置 `CUDA_MANAGED_FORCE_DEVICE_ALLOC=1` 以简化通道内存处理。
## 分析
### 指令直方图 (proton_instr_histogram)
- 统计由时钟读取分隔的区域内每个 warp 的 SASS 指令助记符(启动/停止模型;不支持嵌套区域)
- 输出:每次 kernel 启动生成一个 CSV,包含列 `warp_id,region_id,instruction,count`
示例 (Triton/Proton + IPC):
```
cd ~/CUTracer/tests/proton_tests
# 1) 使用 CUTracer 收集 histogram
CUDA_INJECTION64_PATH=~/CUTracer/lib/cutracer.so \
CUTRACER_ANALYSIS=proton_instr_histogram \
KERNEL_FILTERS=add_kernel \
python ./vector-add-instrumented.py
# 2) 不使用 CUTracer 运行以生成干净的 Chrome trace
python ./vector-add-instrumented.py
# 3) 合并并计算 IPC
python ~/CUTracer/scripts/parse_instr_hist_trace.py \
--chrome-trace ./vector.chrome_trace \
--cutracer-trace ./kernel_*_add_kernel_hist.csv \
--cutracer-log ./cutracer_main_*.log \
--output vectoradd_ipc.csv
```
### 死锁 / 挂起检测 (deadlock_detection)
- 通过识别卡在稳定 PC 循环中的 warp 来检测持续挂起;如果情况持续,记录日志并发送 SIGTERM→SIGKILL
- 需要 `reg_trace`(自动启用)
示例(故意循环):
```
cd ~/CUTracer/tests/hang_test
CUDA_INJECTION64_PATH=~/CUTracer/lib/cutracer.so \
CUTRACER_ANALYSIS=deadlock_detection \
python ./test_hang.py
```
### 数据竞争检测 (random_delay)
- 数据竞争依赖于时序,通常凭运气通过。此分析通过在同步指令前注入延迟来使用随机延迟注入检测竞争,打乱时序并迫使隐藏的竞争显现
- 每个插桩点随机启用/禁用(50% 概率),并带有固定的延迟值
- 需要设置 `CUTRACER_DELAY_NS`
示例:
```
CUTRACER_DELAY_NS=10000 \
CUTRACER_ANALYSIS=random_delay \
CUDA_INJECTION64_PATH=~/CUTracer/lib/cutracer.so \
python3 your_kernel.py
```
#### 延迟转储与重放
CUTracer 支持将延迟配置转储到 JSON,以便确定性地复现数据竞争:
- **转储模式**:设置 `CUTRACER_DELAY_DUMP_PATH` 以将随机插桩模式保存到 JSON 文件
- **重放模式**:设置 `CUTRACER_DELAY_LOAD_PATH` 以加载保存的配置并复现完全相同的延迟模式
**注意**:不能同时使用两者。
**工作流程**:
1. 使用 `CUTRACER_DELAY_DUMP_PATH=/tmp/config.json` 运行以记录延迟模式
2. 当发生故障时,保存配置文件
3. 使用 `CUTRACER_DELAY_LOAD_PATH=/tmp/config.json` 重放以进行确定性复现
## 示例
[`examples/`](examples/) 目录包含常见工作流的参考追踪输出:
- **[Proton Trace](examples/proton_trace/)** -- 示例指令直方图 CSV、CUTracer 日志,以及解释 Triton 向量加法 kernel 端到端 proton 插桩工作流的 README
## 故障排除
- 没有 CSV/日志:检查 `CUDA_INJECTION64_PATH`、`KERNEL_FILTERS` 和写入权限
- 直方图为空:确保 kernel 发出时钟指令(例如 Triton `pl.scope`)
- 开销高:首选仅操作码模式;缩小过滤器范围;使用 `INSTR_BEGIN/INSTR_END`
- CUDA Graph/流捕获:数据在 `cuGraphLaunch` 退出时刷新;确保流同步
- IPC 合并问题:使用解析器标志解决 warp 不匹配和 kernel 哈希歧义
## 许可证
本仓库包含 MIT 许可证 和 BSD-3-Clause 许可证 (NVIDIA) 下的代码。详情请参阅 [LICENSE](LICENSE) 和 [LICENSE-BSD](LICENSE-BSD)。
## 更多文档
完整文档位于 [Wiki](https://github.com/facebookresearch/CUTracer/wiki)。关键主题包括快速入门、分析、后处理、配置、输出、API 与数据结构、开发者指南和故障排除。
标签:C++, CUDA, Facebook Research, GPGPU, GPU安全, HPC, NVBit, Vectored Exception Handling, 二进制插桩, 云资产清单, 内核追踪, 动态二进制分析, 威胁情报, 并发分析, 开发者工具, 性能分析, 指令直方图, 数据擦除, 数据竞争, 死锁检测, 逆向工具, 逆向工程