Visual Studio远程调试Windows上C++程序的几种方式

背景

远程调试(Remote Debugging)的原理可以见下图:
remote-debugger-client-apps

可以看到,远程调试是通过网络进行通信(使用TCP协议)的,将远程程序的运行信息和Visual Studio的控制信息通过网络互传。如果一些特殊的BUG发生在没有网络的情况下,那么远程调试就派不上用场了。

其次,远程调试需要在被调试的目标机器上部署一个程序(Remote tools),这个程序msvsmon.exe的版本必须要和Visual Studio的版本一样。

Remote tools可以下载https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019#download-and-install-the-remote-tools,但是在安装Visual Studio的时候,这个东西是集成到安装目录中的,可以参考https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019#fileshare_msvsmon

有了这些必备条件就可以进行远程调试了。

远程调试应用场景

Case1

目标机器上的程序运行异常(比如卡住,运行结果和预期相悖),想直接附加到目标程序上看看情况。

Case2

目标机器上的程序一旦启动就异常,想调试下目标程序在启动过程中的行为。

Case3

不想在开发机上直接运行目标程序(这个挺常见的,因为开发的程序经常会把自己的电脑搞得乱七八糟的),于是把目标程序运行在别的机器上,远程调试目标程序。

msvsmon.exe的设置

启动之前最好关闭防火墙(运行firewall.cpl可以直接打开防火墙配置),保证开发机和目标机器能够相互ping通。

这里最好使用管理员启动msvsmon.exe,启动后会看到下图界面

在这里插入图片描述

在这里插入图片描述

这里可以看到msvsmon.exe的默认TCP端口是4024,不要改动;身份验证模式为了简单,选择无身份验证并勾选允许任何用户进行调试;最长空闲时间默认为900秒,这里多加几个零,不然空闲了就会把调试器关掉。

演示环境

我的开发机的IP地址是172.18.165.25;目标机器是我的一个虚拟机,IP地址是192.168.174.130,这里的虚拟机网络设置为NAT模式,所以才会出现192的IP,也可以选择桥接模式,这样开发机和目标机器的IP就在同一网段了。

附加程序

附加程序通常用于调试远程还在运行中并且有问题的程序,操作相对简单。在Visual Studio 2019中的调试 -> 附加到进程。进行如下设置:

在这里插入图片描述

连接类型选择远程(无身份验证);连接目标填入目标机器的IP地址;勾选显示所有用户进程;点击刷新,就可以看到目标机器的所有进程了,这里要调试的进程是ConsoleApplication4.exe。因此选择这个进程附加。这里要注意,源码调试进程需要对应的源代码和PDB,这里PDB要么存在本地,要么存在远端服务器上,这里要配置好。

注意,应用程序和PDB必须一一对应,否则无法调试;但是源代码和应用程序不一样也是可以调试的(比如对应源代码新增了几行或者删除了几行,只要改动不大,一般都不影响调试),调试 -> 选项 -> 调试 -> 常规中取消勾选要求源文件与原始版本完全匹配

远程启动

远程启动要在项目的属性页中的调试中配置目标程序路径等一系列信息:

在这里插入图片描述

这里说一下各个选项的注意事项:

  • 远程命令:填目标机器上的目标程序所在位置的绝对路径
  • 远程命令参数:同程序运行所需额外参数一样
  • 工作目录:除非要指定进程的工作目录,否者就默认填目标程序所在目录
  • 远程服务器名称:填目标机器的IP地址
  • 连接:选择不带身份验证的远程访问
  • 部署目录:这个下面重点讲一下,如果应用场景是Case3,请忽略这个选项
  • 其他要部署的文件:这个下面重点讲一下,如果应用场景是Case3,请忽略这个选项

这样就可以远程启动调试程序了。其实要配置这么多有点麻烦,刚刚说了,附加程序调试是最简单的,因此这里可以利用IsDebuggerPresent和DebugBreak在Windows项目中的应用来简化这个过程。

部署目录

部署目录这个选项专门应用于Case3。你想把自己的程序放在别的机器上运行,并且远程调试代码。

最直接的方法:在目标机器上编译链接程序,然后拷贝到目标机器上去,每编译一次,就拷贝一次,这样可以达到目的。

最直接的方法效率是很低下的,能不能编译、拷贝、运行全链路一键运行呢,是可以的,要利用这个部署目录。

在这里插入图片描述

这是Visual Studio中的原话,意思就是会把你的项目输出直接复制到目标机器上,注意哦,假设你的项目输出是exe或者dll,就只会复制exe或者dll过去,至于输出项目的其他文件就要自己处理了。如果文件不多,就可以利用其他要部署的文件这个选项了。

只要填了部署目录这个选项,就可以在项目的右键属性上出现部署这个选项,点这个部署就可以在本地先输出程序,然后拷贝到目标机器上;

如果你想一键编译、部署,运行,那么就需要在项目的配置管理器中勾选部署这个选项。

在这里插入图片描述

直接运行,就直接远程调试了:

在这里插入图片描述

其他方法

上面的东西基本上可以满足绝大部分调试需求了。但是部署的时候只能部署exe或者dll。因此项目输出的其他内容可以在第一次全部拷贝到目标机器上,因此这些东西基本上是不变的,每次改动编译只会影响到exe,把exe拷贝过去其实就可以了;

加入到Visual Studio的文件也是可以作为部署内容拷贝到目标机器上的,文件的属性 -> 常规 -> 内容选择是,就可以把文件部署到目标机器的指定目录中;

由于我一般使用虚拟机作为目标机器,虚拟机上有一个共享文件夹的功能:

在这里插入图片描述

勾选在Windows客户机中映射为网络驱动器,就可以在目标机器上的我的电脑中看到这个网络磁盘

在这里插入图片描述

点进去可以看到你共享的Visual Studio输出目录。这一步间接地把文件在开发机和目标机同步了,因此,直接远程调试就行,不用再部署;

还有一种方法,就是利用Windows的网络发现,把目标机的一个文件夹共享出去,然后Visual Studio输出目录选择这个网络共享文件夹,这样也可以不用部署就能同步文件了。

总结

调试的方法千千万万种,要根据实际情况变通,本篇文章只是简单介绍了下远程调试的用法。

参考

发布了299 篇原创文章 · 获赞 353 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/FlushHip/article/details/104022999