论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
软件与程序人生
›
后端开发
›
.Net
›
dotnet 调试应用启动闪退的方法
dotnet 调试应用启动闪退的方法
八卦阵
金牌会员
|
2022-6-23 14:30:26
|
显示全部楼层
|
阅读模式
楼主
主题
844
|
帖子
844
|
积分
2532
应用程序如果启动即闪退,那大部分时候日志模块还没初始化完成,很难通过应用自身的启动流程了解到应用启动失败的原因。本文来告诉几个不同的方法用来调查应用启动失败的原因
应用启动失败的原因可能有很多,例如系统环境问题,例如写个点逗比代码,例如调用某个带毒的库。如果应用启动失败,可以在开发环境上复现,那无疑是十分好的事情,因为咱可以使用开发环境强大的 VisualStudio 调试工具进行调试
使用 VisualStudio 调试应用启动失败
在有符号的配合下,使用 VisualStudio 定位应用软件启动失败在大多数时候都是比较轻松的。当然,没有符号的话,也没多少问题,至少可以快速定位到是哪个模块
使用 VisualStudio 定位应用软件启动失败的方法是让 VisualStudio 启动应用且进入调试模式。做法就是随便找一个 dotnet 6 的项目,当然,如果是所要调试的应用的对应版本的代码的项目那是最好的。点击设置调试属性,设置应用作为启动路径
在 VisualStudio 2022 下,打开设置调试属性的界面可以是在项目上进行右击,然后点击属性,找到调试页面,点击打开调试启动配置文件即可看到,如下图
接着点击创建新配置文件,选择可执行文件
接下来选择需要调试启动失败的应用的路径
为了同时捕获一些本机异常,还请勾选“启用本机代码调试”也就是混合调试模式。本机异常包括 Window Runtime 抛出的异常,基础的 Win32 调用包含的非返回值的错误的异常,以及外部 C++ 等库的异常等
为了提升调试的成功率,还请在 VisualStudio 设置里面,将所有的异常都打开进行捕获,同时关闭仅我的代码调试。打开所有异常捕获的方法是在 调试->窗口->异常设置 里面进行配置。简单来说就是将能打钩的全部打上,当然,你要是熟悉的话,那就少打钩一些咯,反正多打钩也没啥问题
关闭仅我的代码可以让你调试到一些被优化的代码。在咱 dotnet 的程序集里面,对 Debug 下和 Release 下最大的不同在于勾选了优化代码。如果勾选了仅我的代码调试,那将只调试 Debug 生成的程序集,而默认忽略对 Release 的程序集的记录。在大部分的调试下,这个模式都可以减少发布的程序集的干扰,可以更加方便调试业务代码。但是当前是在调试启动失败,启动失败可能是库的锅,需要调试发布的程序集,推荐关闭仅我的代码调试。关闭的方法是在 VisualStudio 的 工具-> 选项 -> 调试 里面,去掉 启用“仅我的代码” 的选项
完成配置之后,在 VisualStudio 里面,选择刚才创建的新配置作为启动项进行启动
推荐是第一次调试可以快速过,看看是不是有异常触发,逐步去掉那些不影响启动异常的干扰,尝试找到导致启动失败的异常,即可进行快速定位
而启动失败还有一个隐藏的原因是写了逗比代码,自己退出的。那就需要自己进行调试,找到是哪个模块退出了应用,可以在第一次调试的时候,通过输出窗口找到应用的退出码是多少,辅助定位逻辑。如果退出码是一个零,那找找是不是存在 Environment.Exit(0); 类似的代码,可以全局进行字符串查找对应的代码。或者是 Main 函数执行完成,例如在 WPF 里面调用了 Application.Current.Shutdown 进行退出
在开发环境上遇到应用启动失败,大部分时候都可以在 VisualStudio 的帮助下快速定位到为什么启动失败
但是如果应用只是在用户的设备上才失败,那就没那么好玩了,接下来将告诉大家如何调试用户端的应用启动失败
使用 dnSpy 调试应用启动失败
在用户的设备上,如果应用启动失败了,如果此时应用自己的日志模块还没初始化完成,那也不用慌,系统的事件查看器可能可以帮忙到你。打开系统的事件查看器,里面也许记录了一些应用启动失败的原因,例如是系统环境问题,比如是系统缺少了某个库,或者是驱动问题。我之前很经常遇到的就是 WPF 应用启动失败是由显卡驱动导致的,不过显卡驱动问题基本上用不到多少的调试,稍微看一下就能看到了,系统的各个部分都会很奇怪
如何打开系统的事件查看器?在 Win10 下,右击开始菜单按钮,点击事件查看器即可打开。打开之后,大部分时候都可以先去看 Windows 日志里面的应用程序的日志,里面也许有记录应用的启动失败原因
但是有时候事件查看器记录的也很迷,如下面例子的启动失败的记录
系统记录了两条相关的错误日志,一条是 .NET Runtime 错误日志,如下内容
Application: KajijuniLiguqujokemka.exe
CoreCLR Version: 6.0.522.21309
.NET Version: 6.0.5
Description: The process was terminated due to an internal error in the .NET Runtime at IP 00007FF9DAEBDA03 (00007FF9DACF0000) with exit code c0000005.
复制代码
另一条是 Application Error 日志,内容如下
错误应用程序名称: KajijuniLiguqujokemka.exe,版本: 1.0.0.0,时间戳: 0x62571213
错误模块名称: coreclr.dll,版本: 6.0.522.21309,时间戳: 0x625708f4
异常代码: 0xc0000005
错误偏移量: 0x00000000001cda03
错误进程 ID: 0x3814
错误应用程序启动时间: 0x01d882fdfe019fc7
错误应用程序路径: C:\lindexi\Code\lindexi\BeyajaydahifallChecheecaifelwarlerenel\KajijuniLiguqujokemka\bin\Debug\net6.0-windows\KajijuniLiguqujokemka.exe
错误模块路径: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.5\coreclr.dll
报告 ID: 45232171-a61e-46fa-b80b-248ad12f5fef
错误程序包全名:
错误程序包相对应用程序 ID:
复制代码
这两条日志没有能给咱很好的一个调试思路,只能说明应用确实挂了而已。不能说明是应用自己写了逗比代码,也不能证明是系统环境问题,也不能证明是调用库的问题。想要了解为什么,只能继续往下进行调试
通过 dnSpy 神器可以辅助在用户端进行调试。根本原因在于 VisualStudio 太庞大了,在用户端安装不太现实。但 dnSpy 是非常轻巧的,可以免安装使用。相当于在用户端跑一个轻巧的 VisualStudio 调试工具
支持 dotnet 6 版本的 dnSpy 下载地址请看
支持 dotnet 6 的 dnSpy 神器版本
调试的思路和上文的使用 VisuslStudio 调试的差不多,有稍微一点不同的是,需要先将要调试的 Exe 拖入到 dnSpy 中,然后点击此 Exe 进行调试。同样需要勾选异常等
使用 dnSpy 调试还有一个好处是,可以无须任何符号即可进行调试,十分方便
使用 ProcDump 进行 DUMP 分析
但是如果应用的启动失败不是每次都复现的,是概率复现的,那就不好玩了。以上两个方法都是需要进行调试启动的,而大家都知道,调试模式下和非调试模式下是有差别的,例如多线程执行的差别。如果刚好启动是因为线程安全导致的问题,那么调试下也许是复现不到的。对于不是每次都失败的应用启动,进行调试是非常想砸键盘的,有时候调试的好好的,应用就启动成功了。有时候觉得没问题,按下继续,应用就启动失败了
或者是在用户端,用户有情绪了,不适合进行慢慢的调试。此时可以用到 ProcDump 工具辅助,在应用启动时候的时候,将失败时做一个 DUMP 文件,然后咱就可以将这个 DUMP 传回开发的设备上慢慢进行分析
这个 ProcDump 是微软极品工具箱的一个很有名的工具
官方下载地址:
https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump
根据官方文档可以了解到使用方法是在命令行使用如下参数,即可做到在应用因为异常挂掉自动捕获 DUMP 文件
procdump.exe -e -t -w -ma <进程名>
复制代码
参数的含义如下
-e : 当进程遇到未经处理的异常时写入转储
-t : 进程终止时写入转储。如果应用启动失败是自己逗比或者某个库逗比调用了退出进程的方法,那也可以使用捕获到
-w : 等待指定的进程启动。大部分时候都是先运行 ProcDump 工具,然后再启动应用,这样 ProcDump 相当于监控应用启动失败或退出。如此即可采用 ProcDump 启动进程调试应用启动闪退
-ma : 获取的是 Full Dump 文件,也就是包含所有内容的 DUMP 文件,虽然这个 DUMP 比较大,但是调试会根据方便。如果传输过程比较难,而且开发者也熟悉调试 DUMP 可以换用 -mm 命名写入小型 DUMP 文件
假定需要调试的启动失败的应用是 KajijuniLiguqujokemka.exe 应用,那么执行的命令如下
procdump.exe -e -t -w -ma <进程名>KajijuniLiguqujokemka
复制代码
如此即可在应用启动闪退自动创建 DUMP 文件。创建好的 DUMP 文件可以采用 7z 工具压缩一下再传回开发机器,使用 7z 可以极大压缩 DUMP 文件,因为 DUMP 文件里面很多数据都是全 0 的
拿到 DUMP 文件之后,就需要开启 DUMP 调试了。最简单的 DUMP 调试是打开 VisualStudio 将 DUMP 文件拖进入,然后如开始的步骤先配置一下,然后点击使用混合进行调试即可
核心是看调用堆栈,和局部变量窗口,找到是哪个模块抛出异常或者退出。如果 VisualStudio 无法帮到你,那就只能换成 WinDbg 啦,不过这又是另外一个故事了
大家可以尝试使用我放在
github
的代码进行测试
更多请看
dotnet 代码调试方法
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
八卦阵
金牌会员
这个人很懒什么都没写!
楼主热帖
不可思议但又无处不在的漏洞,WEB安全 ...
【历史上的今天】6 月 2 日:苹果推出 ...
C#实现HTTP访问类HttpHelper
开源共建 | Dinky 扩展批流统一数据集 ...
企业应用超融合架构的设计实例及超融合 ...
ClickHouse 查询优化详细介绍
Python字符串替换的3种方法
袋鼠云春季生长大会圆满落幕,带来数实 ...
【软考】系统集成项目管理工程师(二) ...
GreatSQL vs MySQL性能测试来了,速围 ...
标签云
挺好的
服务器
快速回复
返回顶部
返回列表