VSCode用gdbserver调试Wine下32位MinGW交叉编译C/C++程序失败
尝试在VSCode中调试使用i686-w64-mingw32-g++-posix交叉编译生成的Windows平台hello world程序时,VSCode无法成功附加到gdbserver进程。
VSCode项目配套模板仓库地址:https://github.com/aleksas/vscode-wine-mingw-boilerplate
Linux环境交叉编译Windows应用
编译器已在cmake套件配置中预先指定:C代码使用i686-w64-mingw32-gcc-posix、C++代码使用i686-w64-mingw32-g++-posix。
构建cmake项目后会生成./build/hello.exe文件,执行命令wine ./build/hello.exe可正常运行程序。
命令行下gdb附加gdbserver验证
参考公开调试方案,首先执行命令启动gdbserver:wine Z:/usr/share/win32/gdbserver.exe localhost:3456 /workspace/build/hello.exe
再执行命令/usr/bin/i686-w64-mingw32-gdb --eval-command='target remote 127.0.0.1:3456' /workspace/build/hello.exe附加调试器。为简化操作,已添加/usr/bin/gdbservershell脚本,启动时自动执行wine Z:/usr/share/win32/gdbserver.exe $@命令,无需手动输入完整wine调用命令。
命令行调试流程运行完全正常,调试器可正常加载符号,输出参考如下:
... Type "apropos word" to search for commands related to "word"... Reading symbols from /workspace/build/hello.exe...done. Remote debugging using 127.0.0.1:3456 Reading C:/windows/system32/ntdll.dll from remote target... warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead. Reading C:/windows/system32/kernel32.dll from remote target... Reading C:/windows/system32/kernelbase.dll from remote target... Reading C:/windows/system32/msvcrt.dll from remote target... 0x7bc51a41 in DbgBreakPoint@0 () from target:C:/windows/system32/ntdll.dll (gdb)
该阶段所有功能均无异常。
VSCode调试配置
按照VSCode官方C++调试配置说明,在.vscode目录下添加launch.json文件配置调试器,在配置中自定义了gdb、gdbserver的运行路径与启动参数。
VSCode调试异常现象
启动调试配置后gdbserver进程可正常拉起,但无法进入预期的断点调试流程。等配置中设定的调试服务启动超时阈值触发后,会弹出错误提示Unable to start debugging. No process is associated with this object.,调试流程直接终止。
额外验证结果:超时触发前,手动执行命令/usr/bin/i686-w64-mingw32-gdb --eval-command='target remote 127.0.0.1:3456' /workspace/build/hello.exe,可以正常附加到VSCode启动的gdbserver进程,说明gdbserver本身启动、监听端口均正常。
这个报错由三个核心问题共同导致:
- 自定义的
/usr/bin/gdbserver是shell包装脚本,VSCode的C/C++扩展启动gdbserver后,会监控启动进程的PID,它实际跟踪的是shell脚本的PID,而非wine运行的Windows版gdbserver的实际PID;shell脚本启动wine进程后自身会立即退出,VSCode检测到跟踪的进程退出,就会抛出“无关联进程”的错误。 - VSCode默认启动gdb连接gdbserver时使用
target extended-remote模式,和手动调试用的target remote模式不兼容,即使gdbserver正常监听也会出现连接逻辑异常。 - Windows版gdbserver通过wine运行时,输出的“端口监听成功”日志格式和原生Linux gdbserver不一致,VSCode内置的日志匹配规则识别不到就绪信号,会一直等待直到触发超时。
按以下步骤修改配置即可解决问题:
- 移除自定义的
/usr/bin/gdbservershell包装脚本,不要通过脚本间接启动gdbserver。 - 修改
.vscode/launch.json配置,直接调用wine启动gdbserver,同时强制gdb使用target remote模式连接,参考配置如下:
{ "version": "0.2.0", "configurations": [ { "name": "Debug Wine EXE", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/hello.exe", "args": [], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/i686-w64-mingw32-gdb", "miDebuggerArgs": "-ex 'set sysroot /usr/i686-w64-mingw32' -ex 'target remote localhost:3456'", "miDebuggerServerPath": "/usr/bin/wine", "miDebuggerServerArgs": [ "Z:/usr/share/win32/gdbserver.exe", "localhost:3456", "${workspaceFolder}/build/hello.exe" ], "timeout": 30000 } ] }
- 如果上述配置仍有异常,可以改用attach模式:先手动通过终端启动gdbserver,再在launch.json中配置
"request": "attach"、"miDebuggerServerAddress": "localhost:3456",跳过VSCode自动启动、监控gdbserver进程的逻辑,直接连接已经就绪的gdbserver端口即可,这种方式稳定性最高。
内容的提问来源于stack exchange,提问作者alex

