mcpField
C
cuda-debugging

cuda-debugging

github.com/mohitmishra786测试与质量269312 次安装18 周前更新
代码仓库

关于 cuda-debugging

面向 CUDA 开发者的调试技能,涵盖内核交互式检查、内存与竞态检测、核心转储分析、设备端 printf 和运行时错误排查。

主要功能

  1. 01使用 cuda-gdb 单步调试内核
  2. 02检测内存错误与竞态
  3. 03分析 GPU 核心转储
  4. 04使用设备端 printf 调试
  5. 05排查 CUDA 错误码

适用场景

  1. 01诊断 GPU 非法内存访问
  2. 02调查间歇性竞态故障
  3. 03逐步检查内核执行
  4. 04排查内核挂起与超时

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill cuda-debugging

安装后在 Claude Code 中输入/cuda-debugging确认已加载。

详细介绍

CUDA 调试

目的

指导 Agent 使用 cuda-gdb 交互式检查 GPU 线程、使用 NVIDIA Compute Sanitizer 自动检测内存错误和竞态、分析 GPU 核心转储、使用设备端 printf,以及排查常见的 CUDA 运行时错误代码。

适用场景

  • 出现 cudaErrorIllegalAddress(700)或设备端段错误
  • 多线程 GPU 代码间歇性出现正确性问题
  • 调试 warp 之间或主机与设备之间的竞态条件
  • 使用 cuda-gdb 逐行执行内核代码
  • 使用 initcheck 验证未初始化内存读取
  • 内核挂起或出现 cudaErrorLaunchTimeout(702)

工作流

1. 为调试构建
# Debug build — disables optimizations, enables device debug
nvcc -G -g -O0 -arch=sm_80 -o app_debug main.cu

# Sanitizer-friendly build (lineinfo helps reports)
nvcc -lineinfo -g -O2 -arch=sm_80 -o app_san main.cu

cuda-gdb 要进行源码级单步调试,必须使用 -G。Sanitizer 可用于优化构建,但 -G 能提供更清晰的行号。

2. Compute Sanitizer — 自动检查
# Memory errors (OOB, misaligned, leak)
compute-sanitizer --tool memcheck ./app_san

# Shared memory and global memory races
compute-sanitizer --tool racecheck ./app_san

# Uninitialized memory reads
compute-sanitizer --tool initcheck ./app_san

# Synchronization errors (missing __syncthreads)
compute-sanitizer --tool synccheck ./app_san

# Verbose with source correlation
compute-sanitizer --tool memcheck --show-reachable=yes --log-file san.log ./app_san

典型的 memcheck 输出:

======== Invalid __global__ write of size 4
========     at 0x1a0 in vector_add(vector_add.cu:12)
========     by thread (0,0,0) in block (0,0,0)
======== Address 0x7f... is out of bounds
3. cuda-gdb 交互式会话
# Launch under cuda-gdb
cuda-gdb ./app_debug

# Or attach to running process
cuda-gdb -p <pid>

常用命令:

# Break at kernel entry
(cuda-gdb) break vector_add
(cuda-gdb) run

# Focus on GPU threads
(cuda-gdb) info cuda kernels
(cuda-gdb) cuda kernel 0
(cuda-gdb) cuda thread (0,0,0)   # block (x,y,z), thread (x,y,z)

# Inspect device memory
(cuda-gdb) print data[i]
(cuda-gdb) x/10f d_ptr

# Step in kernel
(cuda-gdb) cuda step
(cuda-gdb) cuda next

# All threads in block
(cuda-gdb) info cuda threads
(cuda-gdb) cuda thread (0,0,5)
4. 设备端 printf
__global__ void debug_kernel(float *data, int n) {
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    if (i < n) {
        if (i < 5)  // limit output
            printf("thread %d: data[%d] = %f\n", i, i, data[i]);
        data[i] *= 2.0f;
    }
}
# Buffer size for printf (default may truncate)
cuda-gdb) set cuda printf_buffer_size 16777216

检查输出前,使用 cudaDeviceSynchronize() 刷新缓冲区。所有线程过量调用 printf 会导致缓冲区不堪重负。

5. 错误代码排查
代码名称常见原因
700cudaErrorIllegalAddress越界访问、释放后使用、指针错误
701cudaErrorLaunchOutOfResources每个 block 的共享内存或寄存器用量过大
702cudaErrorLaunchTimeout无限循环、TDR 看门狗(Windows/默认 Linux)
719cudaErrorLaunchFailure内核中的断言、栈溢出
// Always check after launch
kernel<<<grid, block>>>(args);
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess)
    fprintf(stderr, "launch: %s\n", cudaGetErrorString(err));
cudaDeviceSynchronize();
err = cudaGetLastError();
if (err != cudaSuccess)
    fprintf(stderr, "exec: %s\n", cudaGetErrorString(err));
6. GPU 核心转储
# Enable coredump (driver 450+)
export CUDA_ENABLE_COREDUMP_ON_EXCEPTION=1
export CUDA_COREDUMP_FILE=/tmp/cuda_coredump_%h.%p

./app_san   # crash generates dump

# Analyze with cuda-gdb
cuda-gdb ./app_san /tmp/cuda_coredump_hostname.pid
(cuda-gdb) cuda coredump load /tmp/cuda_coredump_hostname.pid
(cuda-gdb) bt
(cuda-gdb) info cuda kernels
7. 调试决策树
Crash or wrong results?
├── Consistent wrong values → logic bug; use printf or cuda-gdb
├── Intermittent / depends on size → OOB or race
│   ├── compute-sanitizer --tool memcheck
│   └── compute-sanitizer --tool racecheck
├── Hang / timeout 702 → infinite loop or barrier mismatch
│   └── synccheck; audit __syncthreads paths
└── Works in debug (-G), fails in release → uninitialized mem or race
    └── initcheck + racecheck on release build
8. 多 GPU 和 MIG 说明
# Isolate GPU
CUDA_VISIBLE_DEVICES=0 compute-sanitizer --tool memcheck ./app

# MIG instances appear as separate devices
nvidia-smi -L

常见问题

现象原因解决方法
cuda-gdb 无法在内核中设置断点构建时未使用 -G使用 nvcc -G -g -O0 重新构建
Sanitizer 未报告错误,但崩溃仍然存在异步错误延迟出现在内核后添加 cudaDeviceSynchronize()
printf 没有任何输出缓冲区已满或未同步限制打印量;增大缓冲区;执行同步
racecheck 对原子操作误报使用了非原子的读-改-写操作使用 atomicAdd/atomicCAS
附加失败进程尚未进入 CUDA 上下文在首次调用 cudaMalloc 后设置断点
Windows 上发生 TDR 超时内核运行时间过长拆分内核;使用 cudaDeviceSetLimit 或 regedit 调整 TDR

相关技能

  • skills/gpu/cuda — 内核模式、内存层次结构、启动配置
  • skills/gpu/cuda-profiling — 验证正确性后进行性能分析
  • skills/gpu/gpu-memory-model — 理解竞态和合并访问
  • skills/debuggers/gdb — 与 cuda-gdb 共用的主机端 GDB 命令
  • skills/runtimes/sanitizers — 主机代码的 ASan/TSan 概念
  • skills/kernel/kernel-debugging — 针对驱动程序级问题的 kgdb/kprobes

评论

支持 Markdown