VS远程调试
Visual Studio 远程调试
通常,我们开发软件都是本地编码、编译、调试、运行,确认功能实现正确后将编译好的程序再部署到目标机器运行。但是工作中,总发现会有些场景Bug只在目标机器上出现,此时我们可以在本地的 VS 开发环境中对运行在目标机器上的程序进行远程调试。
1. VS远程调试原理
1.1 目标机器
目标机器,也称客户机器,即负责执行目标程序的机器。远程调试时需要在目标机器上安装和运行远程工具 (Remote Debugger),等待来自开发机器的连接请求。
1.2 开发机器
开发机器,也称编译机器,即开发本地具备编译程序环境的机器,远程调试时会将编译好的程序部署到目标机器上执行。配置 VS 工程,建立与目标机的连接,即可远程调试。
1.3 网络连通
显然,目标机器和开发机器需要网络连接通。
目标机器和开发机器必须通过网络、工作组、家庭组连接,或者通过网线直连;不支持在通过代理连接的两台计算机之间进行调试。
2. 远程调试分类
远程调试可分为:附加到进程与远程Windows调试器两种方式
2.1 附加到进程
附加到进程:需将本地编译完成后的exe与相关dll拷贝至目标电脑;此方式前提是在目标(客户)机器上运行的被调试软件可正常打开。
2.2 远程Windows调试器
远程Windows调试器:配置完部署目录及相关参数后,VS会自动部署相关exe和dll文件,也支持初始化异常等调试
2.3 远程调试部署
3. Remote Debugger部署
3.1 获取工具
-
从VS安装目录拷贝
以Visual Studio 2022为例,本地默认路径为(C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Remote Debugger)
-
从微软官网下载
微软官网下载链接:https://learn.microsoft.com/zh-cn/visualstudio/debugger/remote-debuggin
3.2 拷贝工具
拷贝本地msvsmon.exe和相关dll到目标机器,以Visual Studio 2022为例,本地默认路径为(C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Remote Debugger),有x64、x86、Appx三个版本,根据机器配置拷贝对应文件夹即可:
3.3 配置选项
在目标(客户)电脑打开msvsmon.exe,进行选项配置。详细如下图所示:
3.4 正常效果
远程msvsmon.exe配置成功效果,详细如下图:
3.5 注意事项
-
目标机器上所登录的账户一定要有管理员权限。
-
有时可能会由于防火墙或者认证等原因,导致连接不上的问题,可以在防火墙中开放Remote Debugger所使用的端口。当然,最简单、最极端的方法是完全关闭防火墙。
-
首次打开 Remote Debugger (msvsmon.exe)会出现配置窗口,提醒我们配置一些参数,如果不清楚你的网络连接方式,比较保险的做法是把所有框都勾选上。详细如下图:
-
其它待补充
4. 远程调试方式
4.1 附件到进程
-
在目标电脑,打开需调试进程
-
在本地电脑,用VS打开[调试—>附加到进程]
-
如果是同一局域网内,点击查找输入ip或域名,会自动检测到,然后选择对应的电脑即可(注意:此处Visual Studio有Bug,非同一局域网不要点击查找!不要点击查找!不要点击查找!直接输入ip或域名后直接回车)
-
选择需调试的进程,附加即可
-
附加成功后,VS进入调试
-
至此,局域网附加至进程调试配置结束
4.2 远程Windows调试器
-
切换至远程调试器
-
项目属性中配置相关参数:根据调试需要设置(远程服务器名称为目标电脑IP:端口 )–端口需与之前目标电脑配置的一致
Remote Debugger配置,详细如下图:
项目属性配置,详细如下图:
-
勾选部署项目文件(如遇部署勾选框为灰色,则是上一步部署目录未配置引起)
-
至此配置结束
-
详细调试方法可参考微软官方文档
微软官方调试C++程序链接:https://learn.microsoft.com/zh-cn/visualstudio/debugger/remote-debugging-cpp?view=vs-2022
5. 内网穿透
5.1 原理
由于IPV4采用了动态主机配置协议(DHCP)、无类别域间路由(CIDR)、网络地址转换协议(NAT)等手段来解决地址耗尽的问题。NAT 提供了私有地址到公有地址的转换,这使具有私有 IPv4 地址的设备能够访问其私有网络之外的资源,但主机在局域网中的 IP 地址不能在公网中使用。
由于外网的目标电脑IP无法直接访问,Remote Debugger远程调试外网机器时需要借助第三方内网穿透工具辅助,市面上有很多内网穿透工具可选择,本文列举几个常用的内网穿透工具进行讲解。
5.2 方式一:NATAPP
NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
NATAPP内网穿透流程:
-
注册账号
进入NATAPP官网:https://natapp.cn/
-
注册完成,登录后,购买隧道,购买成功后在“我的隧道”中可查看;日常轻度简单调试可选Free免费购买一个,有带宽、流量、TCP连接数等要求请按需购买
购买隧道注意事项(必须为TCP协议,端口号购买以后可在隧道配置中修改)
-
下载客户端:
进入NATAPP官网下载:https://natapp.cn/#download
-
配置NATAPP
配置NATAPP,解压下载文件,在natapp.exe同级目录下,新建一个config.ini文件
配置config文件内容—其中authtoken必须配置项,详细内容如下:
#将本文件放置于natapp同级目录 程序将读取 [default] 段 #在命令行参数模式如 natapp -authtoken=xxx 等相同参数将会覆盖掉此配置 #命令行参数 -config= 可以指定任意config.ini文件 [default] authtoken=2d32803ccc250247 #对应一条隧道的authtoken clienttoken= #对应客户端的clienttoken,将会忽略authtoken,若无请留空, log=none #log 日志文件,可指定本地文件, none=不做记录,stdout=直接屏幕输出 ,默认为none loglevel=ERROR #日志等级 DEBUG, INFO, WARNING, ERROR 默认为 DEBUG http_proxy= #代理设置 如 http://10.123.10.10:3128 非代理上网用户请务必留空
在我的隧道中复制authtoken,粘贴至配置文件对应位置
-
拷贝至目标电脑
将 natapp.exe 和 config.ini 拷贝至目标电脑运行(注意:natapp.exe、config.ini必须在同一文件夹下)
server.natappfree.cc---目标电脑IP,46821—目标电脑端口。
-
telnet验证配置
可以在开发机器使用telnet命令验证内网穿透是否配置成功(如:telnet server.natappfree.cc 37723)。
注意:此处需要在隧道配置中将本地地址改为目标电脑IP或127.0.0.1
-
本地开发机器配置
在连接目标或者属性中配置即可(注意:目标机器中提示的地址前的tcp://不需要,只需要后面的地址server.natappfree.cc::40548),后续操作参考前面”远程调试方式“章节
注意:此处Visual Studio有Bug,非同一局域网不要点击查找(点击查找找不到穿透后的目标机器),输入ip或域名后直接回车即可。
-
其它
5.2 方式二:SuiDao
SuiDao内网穿透流程:
-
注册账号
注册SuiDao会员官网:https://suidao.io/console.html#/signup
-
注册完成,登录后创建隧道
-
创建隧道注意事项(必须为TCP穿透,端口号创建以后可在隧道配置中修改)
-
下载对应客户端
官网下载SuiDao客户端:https://github.com/FastTunnel/SuiDao/releases
-
在个人中心获取用户客户端登录的AccessKey
-
将下载的客户端拷贝至目标机器,创建启动客户端批处理(参数如:SuiDao.Client --key accesskey)
-
启动后如图:
-
telnet验证配置
-
其它
5.3 方式三:贝锐花生壳
贝锐花生壳内网穿透流程:
-
注册账号
贝锐花生壳官网:https://hsk.oray.com/
-
登录账号后管理界面如下图:
-
客户端界面如下图:
-
远程调试同理,输入目标机器穿透的外网地址即可
-
其它
5.4 三种方式比较
- NATAPP使用说明文档最为详细,配置难度和使用稳定性适中。
- SuiDao开源无需实名认证,但目前只有硅谷节点可用,稳定性稍差。
- 花生壳稳定健壮,客户端和穿透管理页面都有诊断功能,可以快速方便确认穿透问题,但实名认证较NATAPP麻烦。
6. 过程中遇到问题
6.1 远程调试时模块窗口无内容、pdb无法加载等异常情况
如远程调试时模块窗口无内容、pdb无法加载等异常情况,可在 ”附加到“ 配置项中去除”自动“选择,按需选择指定”本机代码“之类的的选项。
6.2 关闭反调试
如程序添加了反调试手段,需要先屏蔽掉反调试相关处理。
6.3 断点无法命中
断点无法命中,提示“当前无法命中断点,还没有为该文档加载任何符号”问题工具->选项→调试→选项→常规,取消勾选“启用仅我的代码”,取消勾选“要求源文件与原始版本完全匹配”
6.4 调试时堆栈变量值与实际不对应,调试流程与代码不一致
编译器开了优化,导致部分代码被优化掉了,工程属性->C/C++->优化→优化 设置为已禁用;工程属性->连接器->调试→生成调试信息 设置为“优化以便于调试 (/DEBUG)”或”生成经过优化以共享和发布的调试信息 (/DEBUG:FULL)“
6.5 pdb符号文件和源文件的关系
Visual Studio 调试器种的符合/PDB文件|Microsoft Learn