Windows 上使用 Visual Studio 远程调试 Linux Qt 程序(SSH 方式实战总结)
一、背景
项目环境:
- Windows 端:Visual Studio 2022
- Linux 端:Deepin / UOS
- Qt 程序:安装包方式部署
- 无编译环境(Linux 上没有 gcc)
- 可执行文件带调试信息(with debug_info, not stripped)
目标:
在 Windows 上通过 Visual Studio 远程调试 Linux 上已安装的 Qt GUI 程序。
二、前提确认
1️⃣ 确认程序带调试符号
在 Linux 上执行:
file /opt/apps/com.hitevision.hhcast/files/duopinghudong
如果看到:
with debug_info, not stripped
说明:
- 可执行文件包含调试信息
- 不需要重新编译
- 可以直接远程调试
2️⃣ 确认 gdb 可用
gdb --version
只要能正常启动即可,不需要完整编译环境。
3️⃣ 确认 ptrace 没有限制
cat /proc/sys/kernel/yama/ptrace_scope
输出应为:
0
如果是 1,需要执行:
sudo sysctl -w kernel.yama.ptrace_scope=0
三、Visual Studio 配置
1️⃣ 安装 Linux 调试支持
在 VS Installer 中安装:
Linux development with C++
2️⃣ 添加 SSH 连接
路径:
工具 → 选项 → Cross Platform → Connection Manager
添加:
- IP:192.168.x.x
- 端口:22
- 用户名
- 密码
⚠ 注意:这里是 SSH 端口 22,不是 gdbserver 端口。
四、正确的调试方式(关键步骤)
第一步:在 Linux 上正常启动程序
不要用 gdb 启动。
直接用桌面图标启动程序。
因为桌面启动会设置:
- LD_LIBRARY_PATH
- QT_PLUGIN_PATH
- DBUS 环境
- DISPLAY 等变量
直接命令行启动很容易崩溃。
第二步:在 VS 中附加到进程
路径:
调试 → 附加到进程
设置:
- 连接类型:SSH
- 连接目标:选择刚才配置的 Linux 主机
- 勾选“显示所有用户的进程”
- 选择进程:duopinghudong
- 代码类型:Native (GDB)
然后点击“附加”。
五、源码路径映射(必做)
调试信息里记录的是 Linux 编译路径,例如:
/home/HHT/workspace/HHCast/HHCastHub_CN_Receiver
而 Windows 本地源码路径是:
D:\project_wh\windows_app
需要做 Source File Map。
路径:
Tools → Options → Debugging → Symbols → Source File Map
添加映射:
/home/HHT/workspace/HHCast/HHCastHub_CN_Receiver
↓
D:\project_wh\windows_app
否则断点会变灰。
六、常见坑总结
1️⃣ process is already traced
如果出现:
process xxx is already traced
说明:
- 之前用 gdbserver attach 过
- 同一进程不能被两个调试器同时 ptrace
解决:
kill gdbserver_pid
或者不要混用 gdbserver 和 SSH attach。
2️⃣ Internal error in MIEngine
如果出现:
Internal error in MIEngine
NullReferenceException
通常原因:
- SSH 端口填错(误填 1234)
- VS Linux 缓存异常
- 远程 shell 不是 bash
解决:
- 确认 SSH 端口是 22
- 删除本地 Linux 缓存目录
- 重启 VS
3️⃣ 命令行启动崩溃
直接运行:
./duopinghudong
崩溃,但桌面能启动。
原因:
- 缺环境变量
解决:
- 用桌面启动
- 或 attach 已运行进程
七、为什么最终选择 SSH attach,而不是 gdbserver?
两种方式对比:
| 方式 | 特点 |
|---|---|
| SSH attach | 简单,稳定,适合已运行 GUI |
| gdbserver | 更底层控制,但容易混淆端口 |
| 直接 gdb run | 容易缺环境 |
在 Deepin / UOS 环境下:
SSH attach 是最稳方案。
八、最终成功状态
调试成功后可以:
- 下断点
- 单步调试
- 查看变量
- 查看线程
- 查看调用栈
Qt GUI 程序继续在 Linux 屏幕上显示。
九、总结
最终远程调试架构:
Windows Visual Studio
↓ SSH
Linux gdb
↓
正在运行的 Qt GUI 程序
关键点:
- 可执行文件必须带 debug_info
- ptrace_scope 必须为 0
- 使用 SSH attach
- 做 Source File Map
如果你愿意,我还能帮你把这篇博客改成:
- CSDN 风格
- 掘金风格
- 技术公众号风格
- 或更偏底层原理分析版本
你打算发到哪里?