SuperAPI AI 工具集

cuda-debugging

部署与运维

查看项目

更新于 10-15 15:12

技能介绍

用途

本技能用于指导代理调试 CUDA 程序,涵盖使用 cuda-gdb 进行交互式 GPU 线程检查、使用 NVIDIA Compute Sanitizer 自动检测内存与竞态问题、GPU core dump 分析、device 端 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

-G 是 cuda-gdb 源码级单步调试所必需的。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. Device 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;
    }
}

设置 printf 缓冲区大小(默认可能截断):

(cuda-gdb) set cuda printf_buffer_size 16777216

检查输出前需用 cudaDeviceSynchronize() 刷新。所有线程的大量 printf 会淹没缓冲区。

5. 错误码排查

代码 名称 常见原因
700 cudaErrorIllegalAddress 越界访问、释放后使用、错误指针
701 cudaErrorLaunchOutOfResources 每块共享内存或寄存器过多
702 cudaErrorLaunchTimeout 无限循环、TDR 看门狗(Windows/默认 Linux)
719 cudaErrorLaunchFailure 内核断言、栈溢出

启动后始终检查错误:

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 core dump

启用 coredump(驱动 450+):

export CUDA_ENABLE_COREDUMP_ON_EXCEPTION=1
export CUDA_COREDUMP_FILE=/tmp/cuda_coredump_%h.%p

./app_san   # crash generates dump

使用 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. 调试决策树

崩溃还是结果错误?

  • 一致的错误值 → 逻辑 bug;使用 printf 或 cuda-gdb
  • 间歇性 / 依赖规模 → 越界或竞态
    • compute-sanitizer --tool memcheck
    • compute-sanitizer --tool racecheck
  • 挂起 / 超时 702 → 无限循环或屏障不匹配
    • synccheck;审查 __syncthreads 路径
  • 调试版(-G)正常,发布版失败 → 未初始化内存或竞态
    • 在发布版上运行 initcheck + racecheck

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
attach 失败 进程不在 CUDA 上下文中 在首次 cudaMalloc 后断点
Windows 下 TDR 超时 内核运行过长 拆分内核;cudaDeviceSetLimit 或修改注册表 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