使用Visual Studio 19调试.net程序的dump文件(转发)
原文链接:https://blog.csdn.net/dap769815768/java/article/details/105506072
应用程序如果运行期间崩溃了,大概率是来不及记录日志的,大部分情况下,进程并不会立即退出,而是弹出一个错误的弹窗。如果错误弹窗里面的信息有限,这个时候可以利用小型转储文件进行调试,查看崩溃那一刻,程序正在干什么。转储文件就相当于快照,记录的是程序某一个时刻的状态,当程序抛出异常的时候,就会停留在抛异常的那个时刻,这个时候你如果创建转储文件,快照记录的正好是抛异常的时刻。快照有点像我们平时debug的时候,打的断点,程序debug遇到断点,停留在某一时刻,这个时刻的相关的变量的值是多少,执行到哪一步,都很清楚,dump文件记录的大概也是这样的一个快照。既然vs可以断点停留,那么就意味着vs可以调试dump文件,下面是使用visual studio 2019调试dump文件的方法。
1)随意写一段小程序,里面包含一个空指针异常,没有捕获,这会导致程序崩溃。比如下面的代码:
object obj = null;
obj.ToString();
2)把上面的小程序生成一个debug包,放到某台测试电脑上,运行它,让他崩溃:
打开windows任务管理器,找到崩溃的进程,右键=》创建转储文件
创建成功后,找到对应的位置,把这个dmp文件拷贝到你的有调试环境的电脑。
3)打开vs。文件=》打开=》文件。打开你刚才导出的文件:
上面的图是打开后的界面,有比较基础的信息统计。我们可以看到进程框架那一项,是64位转储,如果用64位转储,那么你的调试器就必须是64位的。点击使用仅限托管进行调试,就可以像debug那样,调试dmp文件了。这个时候你可能会遇到第一个问题:
无法对此小型转储进行托管调试。未能找到托管的小型转储调试所需的库“mscordbi.dll”(版本“4.0.30319.0”)。请在尝试以下一个或多个步骤后重新启动调试会话:
1. 如果此计算机当前未连接到 Internet,请连接以便能从 Microsoft 下载 dll。
2. 在“调试器”选项下的“符号设置”中指定“mscordbi.dll”的路径。
3. 选择“使用‘仅限本机’进行调试”。
如下图:
这个是因为程序运行的.net环境和vs所在的环境版本不一致造成的,会提示找不到mscordbi.dll这个版本的文件,我不知道是我没有设置好,还是vs在这一块确实有bug,设置符号路径并没有用处,按照这个提示操作,也没有任何用处,查看官方文档,也找不到有用发的信息,网上的信息相当少。这里我提供一下我的解决方案。
a)打开程序运行电脑的这个路径:C:\Windows\Microsoft.NET,这里包含了.net的运行库,比如我这台测试电脑的:
一个是64位的,一个是32位的,有些人可能只有一个文件夹,没有64位那个文件夹,这个并不影响,有的话就去对应的位数文件夹下去找,没有,就在唯一的那个文件夹下找就行了。打开这个文件,里面就包含我们需要的mscordbi版本:
b)把红框的整个文件夹拷贝出来,放到你的调试电脑里面,把刚才的dmp文件放到这里文件夹里面。再用vs打开dmp文件,应该就不会再提示找不到mscordbi了。如果32位的不行就试试64位的。
4)解决掉找不到mscordbi.dll的问题后,再点击使用仅限托管进行调试,这个时候你可能会遇到第二个问题,就是找不到.pdb调试文件:
这个调试文件,必须和你打包的那个一致,如果你的程序中途修改过,重新生了pdb文件,那么你新打包的.pdb文件是不可用的,这里的解决办法是,把你之前拷贝到测试机上的pdb文件拷贝出来到你的本地电脑里,然后点击设置符号路径:
点击添加,把刚才拷贝的pdb的路径放进去:
5)解决掉找不到pdb文件的问题后,再点击使用仅限托管进行调试,代码就调试起来了,可以看到程序停止的位置,和抛出的未处理的异常:
6)如果你打包的时候,勾选了优化代码,那么一些调试信息可能会被优化掉,这个时候调试dmp文件就不一定能看到有用的信息了:
7)如果你打包的时候,设置了不生成pdb文件:
这个时候,你调试dmp文件,是找不到pdb文件的,但是有些情况下,你仍然可以看到异常信息,比如这个例子中,vs虽然提示找不到pdb文件,但是异常信息依旧打出来了:
8)默认情况下,如果你电脑里面包含源文件,vs会根据pdb信息自动定位到,但是如果没有定位到,可以使用vs打开转储文件,在解决方案资源管理器里就可以看到你打开的文件,右键=》属性,就可以设置源文件的路径了:
这里要强调的是,调试dmp文件并不能百分百定位到异常发生的位置,也就是说可能并不一定能帮你定位到问题,因为程序运行出错的那一刻和你进行转储的那一刻可能不在一个时间点,这个时候你的转储文件,是定位不到出问题的位置的。
————————————————
原文链接:https://blog.csdn.net/dap769815768/java/article/details/105506072