一款面向 C/C++ / CUDA 雷达 & 信号处理开发者的 VSCode 调试可视化插件。
在断点处把任意一段连续内存(std::vector / 原生数组 / 裸指针 / thrust::host_vector)一键 Pin 到面板,
即时查看时域、频谱、时频谱、2D 热力图,并支持原始字节导出为 .bin 文件。
目录
环境要求
开发 / 打包本插件
| 组件 | 最低版本 | 说明 |
|---|---|---|
| VSCode | ≥ 1.86 | 插件引擎要求,建议最新稳定版 |
| Node.js | ≥ 18 | 编译 TypeScript 与 vsce package 打包 |
| npm | ≥ 9 | 安装依赖 |
调试目标程序(你被调试的工程)
| 组件 | 最低版本 | 说明 |
|---|---|---|
| GCC + GDB | ≥ 8 | CPU C/C++ 调试(cppdbg);编译选项需 -g -O0 |
| CUDA Toolkit | ≥ 11.0 | 含 nvcc、cuda-gdb、Thrust 头文件 |
| NVIDIA Nsight VSCode Extension | ≥ 2024.1 | CUDA 调试适配器(cuda-gdb 类型) |
| nvcc 编译选项 | -G -g -O0 |
必须带 device 调试符号,否则 breakpoint 与内存读取均失效 |
离线分析导出数据(可选)
| 工具 | 版本 | 说明 |
|---|---|---|
| Python + NumPy | ≥ 3.7 | np.fromfile('x.bin', dtype='<c8') 读取复数 |
| MATLAB | ≥ R2018b | fread 读取裸字节 |
核心功能
| 功能 | 说明 |
|---|---|
| 手动 Pin | 在 VSCode Variables 面板右键 → Pin to Radar Signal Visualizer,无须配置识别规则 |
| DAP readMemory | 通过 Debug Adapter Protocol 直接读裸字节,避开变量子树展开慢 / 截断的问题 |
| 复数支持 | cuFloatComplex / cuDoubleComplex / std::complex<float> / std::complex<double> / float2 / double2 |
| Thrust 容器 | thrust::host_vector<T> 支持(通过 contiguous_storage 私有字段导航,避开 inline 方法) |
| 时域绘图 | 实数波形、复数模值、dB 模值(20·log10|x|) |
| 复数 I/Q 三联视图 | 同卡片显示 I/Q 时域 + 归一化频谱(-0.5 ~ 0.5)+ 时频谱 (STFT) |
| 2D 热力图 | 手动指定 Rows × Cols,将一维数据按行主序展开为热力图(默认 viridis 调色板) 鼠标悬停显示 row / col / value |
| 手动确认绘图 | 所有参数变更(plot type / Length / Rows / Cols)均不自动重绘,必须点击 📊 Plot 按钮,避免半成品状态被误绘 |
数据导出 .bin |
按当前 elementType 以 little-endian 裸字节写入,复数交错 (re,im,re,im,…),可直接 numpy.fromfile |
| Chart.js 刻度优化 | x 轴末端不会再缺失(512 点能看到 511);频谱固定 10 格,中心为 0 |
| CUDA-GDB 兼容 | 同时支持 cppdbg 与 NVIDIA Nsight 的 cuda-gdb |
支持的数据类型
容器
std::vector<T>、std::array<T, N>、std::deque<T>thrust::host_vector<T>- 原生数组
T[N] - 裸指针
T*(需要在使用时手动指定大小,详见下方"裸指针"小节)
元素类型 T
- 浮点:
float/double - 整型:
int/int32_t/uint32_t/short/int16_t/uint16_t/char/int8_t/uint8_t/long/int64_t/uint64_t/long long - 复数:
cuFloatComplex/cuDoubleComplex/std::complex<float>/std::complex<double>/float2/double2
安装:打包成 .vsix 并装到任意工程
1) 在本仓库打包 .vsix
# 仅首次需要全局装一次 vsce
npm install -g @vscode/vsce
# 在本仓库根目录
npm install
npm run compile
vsce package
执行完成会在仓库根目录生成形如 radar-signal-visualizer-0.0.1.vsix 的文件。
如果 vsce 提示 LICENSE / repository 缺失:在
package.json加上"repository"字段,或加--allow-missing-repository参数;提示没有 README 时可加--no-yarn。
2) 安装到任意 VSCode 实例
图形界面:
- VSCode 左侧 Extensions(
Ctrl+Shift+X)→ 点击右上角…→Install from VSIX...→ 选择刚生成的.vsix
命令行:
code --install-extension /path/to/radar-signal-visualizer-0.0.1.vsix
WSL / Remote-SSH 环境:插件需要装在「实际跑调试器的那一端」。如果你在 WSL 里调
cuda-gdb,请在 WSL 那侧的 VSCode 中安装;可在 Extensions 列表里点齿轮 →Install in WSL。
3) 验证安装
- 打开任意带
launch.json的工程,启动调试 - 命中断点后,左侧 Activity Bar 里应能看到雷达图标的 Radar Signals 视图
- 在 Variables 面板任一数组变量上右键 → 出现
Pin to Radar Signal Visualizer即说明安装成功
在你自己的工程中使用
第一步:配置调试器
仅需用 VSCode 内置 / 官方调试器即可,本插件不替换调试器,只是在 DAP 之上读内存。
CPU C/C++(cppdbg + gdb / lldb)
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug (gdb)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/your_app",
"MIMode": "gdb",
"cwd": "${workspaceFolder}",
"stopAtEntry": false
}
]
}
CUDA(cuda-gdb)
需先安装 NVIDIA Nsight Visual Studio Code Edition 扩展。
{
"version": "0.2.0",
"configurations": [
{
"name": "CUDA C++: Launch",
"type": "cuda-gdb",
"request": "launch",
"program": "${workspaceFolder}/build/your_kernel",
"stopAtEntry": false
}
]
}
编译目标程序时务必带调试符号:CPU
-g -O0,CUDA-G -g -O0。
第二步:调试 → Pin → 看图 → 导出
- 在你工程的源文件中下断点,
F5启动调试 - 命中断点后,在左侧 Variables 面板里找到你想观察的数组 / vector / thrust::host_vector / 指针
- 右键 →
Pin to Radar Signal Visualizer - 自动打开
Radar Signal Visualizer面板,卡片即出现 - 调好参数后点击卡片右上的 📊 Plot 渲染图像
- 需要带回原始数据 → 点击 Table 区右侧 💾 Export .bin
裸指针(T* / cuFloatComplex* 等)
裸指针没有大小信息,Pin 时插件会弹输入框让你输入元素个数。
thrust::host_vector
thrust::host_vector<T> 的读取方式与 std::vector<T> 类似。插件通过导航 Thrust 内部存储结构(m_storage.m_begin.m_iterator → 数据指针,m_size → 元素个数)来读取数据,避开可能被内联的 .data() / .size() 方法。
注意:GDB 中 Thrust 类型会带上 inline namespace 前缀(如
thrust::THRUST_200802_SM_520_NS::host_vector<...>),插件已处理此类情况。若 Pin 时弹框提示"无法解析类型",请检查 CUDA Toolkit 版本是否 ≥ 11.0。
thrust::device_vector<T> 暂未支持(数据在 GPU 端,DAP readMemory 需额外适配设备地址空间)。
多次断点
每次断点命中、Step 之后,所有已 Pin 的卡片都会自动重新读内存并刷新 Table,但绘图不会自动刷新——你需要再次点击 📊 Plot(这是刻意设计,避免参数没改完就乱绘)。
使用流程
启动调试 → 命中断点 → Variables 面板右键 Pin
→ 在卡片中选择 Plot Type / Length / Rows×Cols
→ 点击 📊 Plot 渲染
→ (可选)💾 Export .bin 导出原始字节
→ 单步 / Continue → 数据更新 → 再次点击 📊 Plot
绘图模式说明
| Plot Type | 适用 | 内容 |
|---|---|---|
| Time Domain | 实数 | 简单时域波形(蓝色折线) |
| Magnitude | 实数 | |x[n]| 时域曲线 |
| Magnitude (dB) | 实数/复数 | 20·log10|x[n]|,含 -inf 防护 |
| Complex I/Q | 复数 | 三联:I/Q 时域 + 归一化频谱(-0.5..0.5) + STFT 时频谱 |
| 2D Heatmap (|·| intensity) | 一维 → 二维 | 手动指定 Rows × Cols 后按行主序展开;hover 显示 row/col/value(复数另显示 |z|、re、im) |
频谱横坐标:固定 10 格,刻度 -0.5 -0.4 … 0 … 0.4 0.5,中心为 0,方便目测频率。
时域 x 轴:保证显示最右端样本(512 点能看到 511),且自动避开标签视觉重叠(如 500 与 511 太近时合并)。
数据导出
点击 Table 区右侧的 💾 Export .bin 按钮:
- 弹出系统保存对话框,默认目录 = workspace 根
- 默认文件名:
<displayName>_<elementType>_<N>.bin - 文件格式:裸字节流,无 header,little-endian,复数交错
(re, im, re, im, …)
在 NumPy 中读取
| 类型 | dtype |
|---|---|
float |
<f4 |
double |
<f8 |
int32_t / int |
<i4 |
uint32_t / unsigned int |
<u4 |
int16_t |
<i2 |
int8_t / char |
<i1 |
uint8_t |
<u1 |
int64_t / long |
<i8 |
cuFloatComplex / std::complex<float> |
<c8 |
cuDoubleComplex / std::complex<double> |
<c16 |
import numpy as np
x = np.fromfile('prt_signal_cuFloatComplex_65536.bin', dtype='<c8').reshape(64, 1024)
在 MATLAB 中读取
fid = fopen('signal_float_512.bin', 'r');
x = fread(fid, [512, 1], 'float32=>float32');
fclose(fid);
% 复数 cuFloatComplex
fid = fopen('iq.bin', 'r');
raw = fread(fid, 'float32'); % 交错 re,im,re,im
x = complex(raw(1:2:end), raw(2:2:end));
fclose(fid);
配置项
settings.json 中可配:
{
// Table 单页行数
"rsv.tablePageSize": 200
}
开发与调试
监听编译
npm run watch
在 Extension Host 里调试本插件
- 在本仓库根目录用 VSCode 打开
- 按
F5→ 启动 Extension Development Host(已配.vscode/launch.json) - 在新窗口中打开本目录下的
test-workspace/,加载test_radar.cu - 命中断点后右键 Pin 任意变量
测试用例
仓库自带 test-workspace/test_radar.cu,包含:
- 实数
float数组(std::vector<float>) std::complex<float>信号cuFloatComplex设备/主机数组thrust::host_vector<cuFloatComplex>LFM 信号(验证 Thrust 容器支持,数据与lfm_signal一致)1024 × 64多 PRT 帧(前 512 LFM + 后 512 零填充,每个 PRT 相同),最适合验证 2D Heatmap
已知限制
thrust::device_vector<T>暂未支持(数据在 GPU 端,后续版本计划支持)int64_t/uint64_t在数值超过 2^53 时由于 JS Number 精度丢失,导出.bin会失真(绘图本身就有同样限制)- 频谱图采用 Hann 加窗 + 朴素 DFT(O(N²));超长信号(≥ 8192 点)建议在导出后离线分析
- 仅支持连续内存:
std::list/std::map等链表 / 树结构无法 Pin - WSL 下 cuda-gdb 偶尔需要在
launch.json加"environment": [{"name":"CUDA_VISIBLE_DEVICES","value":"0"}]
License
ISC