关于 vvvv-debugging
vvvv-debugging 是面向 vvvv gamma C# 项目的调试配置指南,供需要在 VS Code 或 Visual Studio 中启动或附加调试器的开发者使用。它根据工作区和项目构建方式生成配置,并说明常见调试问题。
主要功能
- 01检测 vvvv 安装和工作区文件
- 02配置 VS Code 启动与附加调试
- 03按 DLL 或源码引用设置构建任务
- 04整理 vvvv 调试启动参数
- 05说明断点与符号排查方法
适用场景
- 01为 vvvv gamma 项目生成调试配置
- 02在运行中的 vvvv 实例上附加调试器
- 03为 DLL 引用项目添加启动前构建
- 04排查断点无法绑定或符号不匹配
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tebjan/ vvvv-skills --skill vvvv-debugging安装后在 Claude Code 中输入/vvvv-debugging确认已加载。
详细介绍
调试 vvvv gamma C# 项目
有关命令行参数和会话文件,请参阅 vvvv-startup 技能。
上下文感知设置工作流
当用户要求设置调试时,请按照此工作流操作。生成任何文件之前,使用 AskUserQuestion 一次性询问所有配置问题。不要假设默认值,务必向用户确认。
1. 检测 vvvv 安装
通过扫描 C:\Program Files\vvvv\ 下的 vvvv_gamma_* 目录,自动查找 vvvv.exe:
ls -d "/c/Program Files/vvvv/vvvv_gamma_"* 2>/dev/null | sort -r
目录名称格式:vvvv_gamma_MAJOR.MINOR[-BUILD-gHASH-PLATFORM]。按版本降序排列。除非没有稳定版本,否则过滤掉 -beta、-alpha、-rc、-test、-dev 版本。
2. 扫描工作区
检测工作区中已有的内容:
.csproj/.sln文件(可能需要也可能不需要构建任务——参见第 3 步).vl文件(可作为--open的候选项)help/文件夹(测试补丁的常见位置)- 已有的
.vscode/launch.json(扩展而非覆盖) - Git 子模块(尤其是
VL.StandardLibs——参见下文的软件包仓库警告) - 从仓库文件夹名称、主
*.vl文件或.csproj<PackageId>中获取软件包名称(用于--editable-packages)
3. 询问用户 — 生成前询问所有问题
重要:生成任何配置之前,必须使用 AskUserQuestion 询问以下所有问题。 使用多问题格式批量询问相关问题。收集完所有答案后再生成 launch.json。
问题组 1:vvvv 版本和补丁
- 使用哪个 vvvv 版本? — 列出检测到的版本,并推荐最新的稳定版本。让用户选择或指定自定义路径。
- 打开哪个 .vl 补丁? — 将找到的
.vl文件列为选项。如果存在help/文件夹,请推荐其中的文件。
问题组 2:启动标志
--debug标志? — 启用断点所需的调试符号,但会降低补丁运行速度。询问:“为断点启用--debug?(启动速度较慢)”默认:快速迭代时选“否”;用户明确需要断点时选“是”。--allowmultiple? — 允许启动第二个 vvvv 实例。询问:“允许启动多个 vvvv 实例吗?如果选‘否’,当 vvvv 已在运行时启动会失败(便于检测未关闭的实例)。”默认:否。--package-repositories? — 指定 vvvv 扫描软件包的文件夹。**警告:如果工作区包含VL.StandardLibs/等 Git 子模块,使用--package-repositories ${workspaceFolder}会导致 vvvv 从源代码重新编译所有核心库,耗时数分钟。**询问:“添加--package-repositories吗?仅当 vvvv 找不到你的软件包时才需要。警告:如果仓库中有 VL.StandardLibs 或其他库子模块,这会触发完整重新编译。”默认:否。--editable-packages? — 从源代码加载指定的软件包。仅在使用--package-repositories时有用。仅在启用 package-repositories 后询问。
问题组 3:构建模式
- 源代码引用还是 DLL? — “你的 .vl 文档是直接引用 .csproj(源代码引用,最常见),还是引用预先构建的 DLL?”源代码引用 = 不添加构建任务。DLL = 添加
preLaunchTask: "build"。
4. 生成配置
仅在所有问题都得到回答后,生成 .vscode/launch.json,并按需生成 .vscode/tasks.json。
始终生成以下配置:
- 包含用户所选标志的启动配置
- 用于连接到已运行实例的“连接到 vvvv”配置
可选生成:
- 如果第一个配置不含
--debug(或反之),则生成另一个带有--debug的启动配置 - 如果选择了 DLL/二进制构建模式,则生成
tasks.json
VS Code launch.json
最简配置(源代码引用,不含额外项)
最简单的配置——只打开一个补丁:
{
"version": "0.2.0",
"configurations": [
{
"name": "vvvv — MyPatch",
"type": "coreclr",
"request": "launch",
"program": "C:\\Program Files\\vvvv\\vvvv_gamma_7.1-win-x64\\vvvv.exe",
"args": [
"-o",
"${workspaceFolder}/help/HowTo Use MyFeature.vl"
],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Attach to vvvv",
"type": "coreclr",
"request": "attach",
"processName": "vvvv.exe"
}
]
}
完整配置(包含所有可选标志)
用户选择启用所有标志时:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with vvvv",
"type": "coreclr",
"request": "launch",
"program": "C:\\Program Files\\vvvv\\vvvv_gamma_7.0-win-x64\\vvvv.exe",
"args": [
"--package-repositories",
"${workspaceFolder}",
"--editable-packages",
"VL.MyPackage*",
"-o",
"${workspaceFolder}/help/HowTo Use MyFeature.vl",
"--debug",
"--allowmultiple"
],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "Attach to vvvv",
"type": "coreclr",
"request": "attach",
"processName": "vvvv.exe"
}
]
}
DLL/二进制引用(需要外部构建)
添加 preLaunchTask,以便在启动 vvvv 前构建 C#:
{
"name": "Debug with vvvv (pre-build)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "C:\\Program Files\\vvvv\\vvvv_gamma_7.0-win-x64\\vvvv.exe",
"args": [
"-o",
"${workspaceFolder}/help/HowTo Use MyFeature.vl",
"--debug"
],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
}
要点:
- 源代码引用请省略
preLaunchTask——vvvv 会通过 Roslyn 处理 C# 编译 - 仅在 DLL/二进制引用或复杂构建场景中添加
preLaunchTask: "build" --debug启用调试符号(断点需要此选项,但会减慢补丁运行)--package-repositories告诉 vvvv 在哪里查找你的包——警告:会重新编译扫描到的文件夹树中找到的任何 VL 库子模块--editable-packages从源代码加载指定的包(支持 glob 模式)-o在启动时打开指定的 .vl 补丁--allowmultiple允许启动第二个 vvvv 实例——省略此选项可检测已失效的实例- 为了便于阅读,请将参数写成数组项(而非单个字符串)
附加到正在运行的 vvvv
当 vvvv 已在运行且你想在不重启的情况下调试时,请使用附加:
{
"name": "Attach to vvvv",
"type": "coreclr",
"request": "attach",
"processName": "vvvv.exe"
}
VS Code tasks.json(仅适用于 DLL/二进制引用配置)
仅当项目需要外部构建(DLL 引用、原生依赖项、Release 构建)时才生成 tasks.json。对于 vvvv 在运行时编译 C# 的源项目引用,请完全跳过此步骤。
使用 dotnet 构建
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": ["build", "${workspaceFolder}/src/MyProject.csproj", "-c", "Debug"],
"problemMatcher": "$msCompile",
"group": { "kind": "build", "isDefault": true }
},
{
"label": "build-release",
"command": "dotnet",
"type": "process",
"args": ["build", "${workspaceFolder}/src/MyProject.csproj", "-c", "Release"],
"problemMatcher": "$msCompile"
}
]
}
使用 MSBuild 构建(适用于 .sln 或需要 Visual Studio 工具链的项目)
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "& 'C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe' '${workspaceFolder}/src/MyProject.sln' -p:Configuration=Debug -p:Platform=x64 -t:Rebuild -v:minimal",
"options": {
"shell": { "executable": "powershell.exe", "args": ["-Command"] }
},
"problemMatcher": "$msCompile",
"group": { "kind": "build", "isDefault": true }
}
]
}
除非项目需要 MSBuild 专属功能,或使用带有平台目标的 .sln,否则优先使用 dotnet build。
Visual Studio 设置
通过外部程序进行调试
- 在 Visual Studio 中打开
.csproj - 调试 > 调试属性(或“项目属性” >“调试” >“常规”)
- 创建新的启动配置文件:
- 命令:
vvvv.exe的路径 - 命令行参数:
-o YourPatch.vl(需要断点时添加--debug) - 工作目录:项目文件夹
- 命令:
- 按 F5 启动并附加调试器
附加到进程
- 正常启动 vvvv(需要断点时添加
--debug) - 调试 > 附加到进程(Ctrl+Alt+P)
- 在进程列表中找到
vvvv.exe - 选择 托管(.NET Core、.NET 5+) 作为代码类型
- 点击“附加”
launchSettings.json(dotnet 工具)
{
"profiles": {
"Debug vvvv": {
"commandName": "Executable",
"executablePath": "C:\\Program Files\\vvvv\\vvvv_gamma_6.8-win-x64\\vvvv.exe",
"commandLineArgs": "-o YourPatch.vl",
"workingDirectory": "$(ProjectDir)"
}
}
}
调试提示
--debug——强制生成调试符号,以确保断点可靠生效,但会增加开销。在 Debug 配置中使用;性能或部署测试时省略。--stoppedonstartup——启动时暂停,以便你在任何 Update() 运行前设置断点--nocache——如果断点无法绑定,则强制从源代码重新编译Debugger.Break()——添加到 C# 代码中,以编程方式触发断点- Update() 中的条件断点——Update() 每帧都会运行,因此请使用命中次数或条件
- 构造函数断点——每次热重载周期也会触发(先 Dispose,再调用新构造函数)
console: "internalConsole"——在 VS Code 调试控制台中捕获 Console.WriteLine 输出- 附加调试器时的行为——附加 .NET 调试器后,vvvv 初始化会同步运行(不会捕获异步异常),因此启动断点能够可靠生效
常见陷阱
-
运行时 tick 和文档 tick 的所有者不同。 进程级 SDK 可能需要整个运行时共用一个 tick,而每个文档都有自己的帧时钟。跟踪已安装运行时的 Update/Draw/Present 顺序,并确认回调实际在哪个位置运行;名称中带有帧结束并不能证明它是 Present 之后的钩子。单个游戏系统的 EndDraw 并不能证明所有系统都已完成渲染。确保共享 SDK 帧标识在常量、资源标签和标记之间保持一致。
-
检出版本的 API 可能与已安装的公共 API 不同。 在编写插件或测试工具之前,请核实目标程序集版本、成员可见性以及实际生成的 API。反编译代码中可见的内部运行时方法不一定能由程序包调用;请使用受支持的公共入口点。
-
C++/CLI 源代码可以生成托管 IL。 使用
/clr:netcore时,请先检查目标方法的生成方式,再选择调试器。即使本机符号匹配,本机源代码断点对于托管方法仍可能无法绑定。调试器表达式求值失败并不能证明该方法从未运行;如果混合模式求值不可用,请检查可访问的托管调用方状态。 -
原生 Windows PDB 必须与加载的二进制文件完全匹配。 将 DLL 的 CodeView RSDS GUID 和 age 与 PDB 标识进行比较。文件名匹配或添加符号目录都无法修复标识不匹配问题。还要检查已加载模块的路径,以及你构建的制品路径。
-
内存计数器衡量的是不同的所有权范围。 进程级专用 GPU 用量与适配器级用量是不同的指标;共享资源和驻留情况可能影响归属。计数器不一致本身既不能证明存在泄漏,也不能排除无法解释的增长。请结合分配/释放生命周期、GPU 栅栏进度和驻留情况进行分析,并在调查期间保持内存预算启用。
-
--package-repositories+ VL.StandardLibs 子模块 — 如果你的工作区包含VL.StandardLibs/git 子模块(常见于 vvvv contrib 仓库),--package-repositories ${workspaceFolder}会导致 vvvv 发现并从源代码重新编译所有标准库。这需要很多分钟,而且几乎从来不是你想要的结果。请省略--package-repositories,或将其指向不包含库子模块的特定子文件夹。 -
--allowmultiple隐藏过时实例 — 不使用此标志时,如果另一个实例正在运行,vvvv 会拒绝启动。这很有用:它会告诉你存在一个过时的 vvvv 进程。使用--allowmultiple时,你可能会意外运行两个实例,消耗双倍资源。 -
--debug会拖慢一切 — 生成调试符号会显著拖慢 vvvv 的实时编译。只有确实需要断点时才启用。快速迭代(测试 UI、检查行为)时,请省略它。
让知识持续增长
为下一位修补者少留一个谜团。首次使用本集合中的任一技能时,若过去 7 天内没有成功检查记录,请将源内容与 tebjan/vvvv-skills 进行比较。若没有记录,则检查一次。在这些技能之间共享一个本地检查时间戳/修订版本;不要在每次调用时都轮询。保留本地扩展和固定的项目版本;检查不代表获得安装更新的许可。若处于离线状态,请记录延期检查,然后继续任务。
实际工作发现问题时,请记录经过测试的 vvvv/程序包版本、最小复现步骤或权威来源,以及观察到的结果。将其他用户的报告视为线索,在验证之前不要当作事实。改进最相关的最小范围说明;不要把一个示例变成通用规则。提交上游前,请删除私人数据并获得发布授权。请参阅贡献政策。已合并的改进会通过用户的安装程序/更新工作流送达,而不是通过本地编辑,也不会自动覆盖所有人的技能。