VS Code附加Unity进程调试C++ DLL断点不命中问题求助
你现在断点一直卡“尝试绑定”本质是三个问题:调试配置填错、调试器和编译工具链不匹配、bazel生成的调试符号路径gdb识别不了,之前用clr类型的调试器只能调C#托管层,根本碰不到C++逻辑,按下面步骤改完就能用:
修正launch.json核心配置
你现在配置里最明显的错误是program字段填了DLL路径——cppdbg附加进程的时候,这个字段必须填加载DLL的主程序也就是Unity.exe的绝对路径,填DLL路径gdb根本找不到正确的进程上下文。
直接用下面的配置替换你现有的launch.json,注意把里面的Unity路径、源码路径换成你本地的实际路径:
{ "version": "0.2.0", "configurations": [ { "name": "Attach to Unity C++ DLL", "type": "cppdbg", "request": "attach", "processId": "${command:pickProcess}", // 替换成你本地Unity.exe的绝对路径,绝对不能填DLL路径 "program": "C:/Program Files/Unity/Hub/Editor/2022.3.xx/Editor/Unity.exe", "MIMode": "gdb", // 确保这个gdb和你编译DLL用的编译器属于同一套工具链 "miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe", // 跳过Unity的反调试检测,避免附加之后进程被锁 "setupCommands": [ {"text": "set follow-fork-mode child", "ignoreFailures": true}, {"text": "set detach-on-fork off", "ignoreFailures": true} ], // 源码路径映射,就是你之前调普通C++项目用的sourceMap等价配置 "sourceFileMap": { // 键是bazel编译时写入符号的沙盒路径,值是你本地存C++源码的根目录 "C:/bazel/execroot/your_project_name": "${workspaceFolder}/NativeSrc" } } ] }
如果你是用MSVC编译的DLL,别硬用gdb,直接把type改成cppvsdbg,删掉MIMode和miDebuggerPath两个字段,用微软官方的C++调试器,对Windows原生二进制的兼容性比gdb好太多,不需要额外装任何调试工具。
修复bazel编译的符号问题
用bazel编译的C++库默认会带几个坑,直接导致gdb读不到调试符号:
- 编译的时候必须加
--compilation_mode=dbg参数,关闭编译优化,生成完整的调试信息,绝对不能用opt或者fastbuild模式编译调试用的DLL - bazel默认会在沙盒临时目录下编译,写入调试符号的源码路径是沙盒里的临时路径,和你本地实际存源码的路径不一致,必须通过上面配置里的
sourceFileMap做路径映射,不然gdb找不到对应源码文件,断点永远绑不上 - 编译完成后检查DLL同目录,确保有和DLL同名的调试符号文件:MinGW编译的会生成
.dll.debug文件,MSVC编译的会生成.pdb文件,符号文件和DLL版本必须完全对应,差一个版本号都读不出来。
验证调试器匹配性
msys2里装的mingw64版本gdb,只能调试用同版本mingw64 gcc/g++编译出来的二进制,如果你编译DLL用的是MSVC、clang或者msys2其他环境的编译器,gdb根本识别不了生成的符号,断点肯定绑不上:
- 附加完进程之后,直接在VS Code调试控制台输入
info sharedlibrary回车,看你的目标DLL(mediapipe_c.dll)那一行的符号加载状态,显示Yes就是符号加载正常,显示No就是工具链不匹配或者符号路径不对 - 如果用cppvsdbg调试,直接在断点窗口看模块加载状态就行,不用输命令。
正确的调试操作顺序
配置改完别乱点,按这个顺序走不会出问题:
- 先开VS Code,在C++源码里打好断点,这时候断点是灰的很正常,因为DLL还没加载
- 打开Unity项目,先点编辑器顶部的Pause按钮,再点Start按钮,让游戏启动后立刻暂停,留够附加时间
- 回到VS Code启动调试,在进程列表里选对应版本的Unity.exe进程附加
- 附加完成后看调试控制台的输出,等看到目标DLL加载完成的日志,断点会自动从灰色变成实心红色,这时候再点Unity的继续按钮,走到DLL的调用逻辑时断点就会正常命中。
补充:Unity导入原生DLL的时候,记得在Inspector面板把DLL的
Load on Startup选项勾上,不然DLL要等到第一次被调用的时候才会加载,加载前断点永远是未绑定状态。
内容的提问来源于stack exchange,提问作者mcExchange
相关产品推荐
相关产品推荐

