dotnet 使用 windbg 运行脚本方式自动批量调试处理 dump 文件
本文将和大家介绍一个简单且实际用途不大的使用 windbg 配合脚本的方式,进行自动化的大批量对 dotnet 系应用的 dump 进行自动化分析调试处理,可以自动根据调试需求输出 dump 文件的一些信息
利用 windbg 执行调试脚本的能力,可以实现自动化调试 dump 文件,将调试 dump 文件获取的信息进行输出,方便进行统一处理
在开始之前先说一下我的需求点是什么。我有大量的用户,我也有大量的不同的软件,这些软件对接进了 dump 平台。所谓 dump 平台实际上就是软件崩了的时候,创建一个 dump 文件,然后不差钱的将 dump 文件传送到我的服务器上。我每天都会堆积几千个 dump 文件,压根调试不过来。我期望能够有一个工具可以辅助我提前预处理一些 dump 文件,比如说将堆栈打印出来等等
打印出来堆栈,我可以导入到聚类算法里面,找到其中崩溃堆栈最多的,重点对其进行处理。或者进行一些时间段异常监控
尽管我在开始时说实际用途不大,但用途不大不代表没有用途。整套玩下来,还是能够减少一点工作量的,且能够带来一丁点的收益的。比如说通过本文介绍的方式,我将海量的 dump 文件的堆栈打印出来,通过聚类算法获取到了,大量的 dump 都是无用的 dump 文件。因为大量的崩溃都是事后现场,即进入了最终崩溃点,非发生异常的点,或者异常发生点是属于类似空异常的类型,没有可用信息。或者是内存溢出,内存不足等通用问题。其他的有用的占比不到百分之一,在这里面就基本归类于用户环境问题占了大半,另一半就是调用的其他团队提供的 C++ 库。用户环境问题中,显卡驱动问题占比居多,这部分带来了确实有用的信息。其次的环境问题是比较杂项的,如第三方注入问题、输入法带崩问题、某些系统组件坏掉。用户环境问题的输出监控还是有用的,但调用的其他团队提供的 C++ 库这个基本上就凉凉了,因为很多团队开发完成就解散了,人和代码都找不到,这些就只能用数据来和产品大佬砍需求了,或者申请资源给他用 C# 代码重写了,或者是考虑跨进程调用了
通过分析用户问题,根据时间加入分析,可以了解到趋势信息。比如说最近某段时间内发现用户环境问题中,在崩溃堆栈里面,关于 Intel 显卡驱动的上升。可以进一步关注是否最近 Intel 的最新显卡驱动更新出现问题,取其中的 dump 文件,通过内部合作渠道反馈给到厂商,请厂商尽快修复问题。再比如最近某段时间内发现某个系统组件出现较高的崩溃率,可进一步关注微软系统更新,如果发现系统更新投毒了,那再给微软反馈一下,让微软修修。通过了解趋势信息可以辅助定位第三方影响问题,不仅包括直接厂商,如 Intel 和微软的,也包括第三方厂商,如搜狗拼音输入法还有上回给我投毒的展盟网络科技等等
尽管上文提到说内存溢出问题用途不大,但是如果带上软件版本号,可能通过趋势分析也是有点用途的。比如说发现了某个版本的内存溢出问题比其他版本高很多,再经一步调查,也许可以看到某个版本引入了某些奇特的逻辑,确实是软件自身的问题,而不是用户环境带来的内存不足问题
内存溢出问题如果发现是某段时间内有很多内存溢出问题,且所有软件版本都升高,那就可能也是第三方影响问题。比如之前调查到的 Intel 或微软的 D3D9On12 部分存在内存溢出问题,导致了大量应用都会多占用更多内存,从而出现内存溢出
但无论如何,本文介绍的这个自动化分析方法都无法百分百减少工作量,只能是辅助作用。本文介绍的自动化分析方法比较适合用在有大量的 dump 文件,人工调试不过来的情况,如果本身团队规模比较小,那就只能用于满足领导们的汇报需求了,比如用于吹质量设计
在 windbg 工具中,可以使用 -c
参数带上脚本文件,大概的命令行格式如下
windbg.exe -z [DUMP文件] -logo [日志输出文件] -c "$<[脚本文件]"
一般来说会先组织工作文件夹,将 dump 文件、脚本文件,以及将要被输出的日志文件都放在一个文件夹里面,将这个文件夹当成工作文件夹。如此即可简化命令行,如在 cmd 里通过 cd 命令进入到工作文件夹里面,再执行命令。如以下命令将分析 lindexi.dmp 文件,输出到 log.txt 里面,采用 script.txt 文件作为脚本
windbg.exe -z lindexi.dmp -logo log.txt -c "$<script.txt"
如在 C# 代码里面,可以在 Process 时指定工作路径,例子的代码如下
Process.Start(new ProcessStartInfo("windbg.exe")
{
WorkingDirectory = @"C:\lindexi\Works",
Arguments = "-z lindexi.dmp -logo log.txt -c \"$<script.txt\""
});
上述代码的 -c
参数后面可以带上执行命令,也可以带上放入执行命令的脚本文件。对于比较复杂的,比较多条的命令,推荐放在脚本文件里面。在 windbg 里面,通过 $<
等前缀识别传入的是脚本文件而不是执行命令
接下来我将告诉大家如何编写这个脚本文件
脚本文件的格式非常简单,就是一行一句命令
根据分析 dotnet 应用的知识,对于 .NET Core 系框架,包括 dotnet 6 和 dotnet 7 和 dotnet 8 和 dotnet 9 等版本,第一步咱应该加载 sos.dll 文件。加载 sos.dll 的方法请参阅 WinDbg 加载 dotnet core 的 sos.dll 辅助调试方法
值得特别说明的是,默认的 dotnet-sos 工具存放的是 x64 的 sos.dll 文件,如果将要分析 dump 的应用是 x86 版本的,还需要更改 .load
的路径。比如我这里是放在 C:\Users\lindexi\.dotnet\tools\.store\dotnet-sos\8.0.510501\dotnet-sos\8.0.510501\tools\net6.0\any\win-x86\sos.dll
路径的
完成加载之后,即可使用 !analyze -v
强大的命令进行自动的分析,这一步能够输出异常等信息出来,非常好用。缺点只是分析时间比较长。如果是自动分析的话,挂着让其慢慢分析就不怕分析速度太慢了
接着使用 !clrstack
命令打印出来 dotnet 的托管堆栈,有时候可以在这里看到具体是哪个模块调用的。以及带上 ~*k
输出更多线程堆栈信息和可选加上 ~*e!clrstack
输出所有线程的托管调用堆栈
最后加上 qq
命令,让 windbg 自行退出。于是执行脚本的时候就可以在分析完成之后自动退出
根据上文编写的简单脚本代码如下
.load C:\Users\lindexi\.dotnet\tools\.store\dotnet-sos\8.0.510501\dotnet-sos\8.0.510501\tools\net6.0\any\win-x86\sos.dll
.echo ==============start=============
!analyze -v
!clrstack
~*k
.echo ==============end=============
qq
可以看到以上脚本带上了 .echo ==============start=============
等命令,这些命令只是为了在日志文件里面输入一些标识,方便后续咱编写代码读取日志文件,获取到一些 !analyze -v
和 !clrstack
命令输出的信息。完成以上步骤,接下来就是按照自己的喜好,编写一些 C# 逻辑,让 WinDbg 跑起来,自动分析 dump 文件。然后读取分析结果的日志文件,分析日志文件里面的内容。如此就完成了自动编写 DUMP 分析工具平台了。额外的,在现实使用中,可能还会带上 -y
参数,用于指定符号文件夹,减少加载符号时,拉取符号的耗时,参数是 -y [符号文件夹]
的格式
dotnet 使用 windbg 运行脚本方式自动批量调试处理 dump 文件的更多相关文章
- 开源一套原创文本处理工具:Java+Bat脚本实现自动批量处理对账单工具
原创/朱季谦 这款工具是笔者在2018年初开发完成的,时隔两载,偶然想起这款小工具,于是,决定将其开源,若有人需要做类似Java批处理实现整理文档的工具,可参考该工具逻辑思路来实现. 该工具是运行在w ...
- Java IDEA根据database以及脚本代码自动生成DO,DAO,SqlMapper文件(一)
根据数据库代码自动生成的插件挺多的,这里主要分享两种: 1.根据database以及脚本代码自动生成 2.根据mybatis-generator-core自动生成(下一章节进行分享,包含sqlserv ...
- Windbg内核调试之四: Dump文件分析
Dump 文件分析很大程度上就是分析蓝屏产生的原因.这种系统级的错误算是Windows提示错误中比较严重的一种(更严重的还有启动黑屏等硬件或软件兼容性错误等等).说它是比较严重,是因为毕竟Window ...
- sublime打开文件时自动生成并打开.dump文件
GBK Encoding Support 没有安装前打开ASNI格式编码文件会乱码,安装成功重启则可以打开正常 关于.dump文件生成的解释: 当打开一个非utf-8格式且包含汉字的文件时,subli ...
- shell脚本示例:批量比较多个文件的内容是否相同
bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 要比较两个文件的内容是否完全一致,可以简单地使用diff命令. ...
- PHP运行脚本
PHP运行脚本 php.exe -f "php文件" php.exe -r "php代码" 例如:在cmd中 C:\Users\Administrator.SK ...
- ubuntu20.04开机自动运行脚本实例
在 Ubuntu 20.04 中,/etc/rc.local 文件仍然存在,但不再默认启用,因为它已经被 systemd 代替.下面是使用systemd开机执行的脚本的实例: 1.编写脚本myscri ...
- ASP.NET CORE dotnet run 命令使用debug方式运行
由于我的开发环境比较复杂,每次调试一套项目都要启动好几个VS,比较繁琐,今天决定换一种方式调试,对于不该改动的代码的附加项目直接使用dotnet run命令以debug的运行方式运行, 一开始无法运行 ...
- 在shell中运行以不同方式运行脚本
在shell当中,可以有3中方式运行脚本: 1 . ./script_name 或者source ./script_name 2 直接./script_name 3 ./script_name &am ...
- 配置 Tomcat 以服务方式自动运行
接手一台用 Tomcat 跑着 Java Web 应用的 Linux CentOS 服务器,通过镜像的方式更换服务器后站点无法访问,发现是因为 Tomcat 不能在服务器启动后自动启动,于是基于 in ...
随机推荐
- JavaScript实现防抖与节流
1. 引言 有这么一种场景:某个页面表单按钮设置了点击提交事件,有时因为网络不好,点击后后台服务端很久才返回信息,然而用户因等待许久已经多次点击导致多次发送数据,实际上服务器只需要一次发送的数据即可 ...
- 记录--啊?Vue是有三种路由模式的?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 众所周知,vue路由模式常见的有 history 和 hash 模式,但其实还有一种方式-abstract模式(了解一哈~) 别急,本文我 ...
- Openlayers 加载ArcGIS Server切片服务(自定义切片方案)
背景 最近遇到一个需求,要使用OpenLayer加载ArcGIS Server发布的服务.如果直接拷贝OpenLayer提供的在线官方Demo,然后修改下地图服务地址是跑不通的,这是因为OpenLay ...
- 记录-js基础练习题
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 隔行换色(%): window.onload = function() { var aLi = document.getElementsB ...
- API接口开发规范
API接口是不同软件系统之间进行通信的重要方式,良好的API接口设计规范可以提高系统的可维护性.可扩展性和易用性.本文介绍了一套详细的API接口开发规范,包括命名规范.请求和响应规范.安全规范等内容, ...
- 纯前端实现 JPG 图片压缩 | canvas
在线 Demo 体验地址 →: https://demos.sugarat.top/pages/jpg-compress/ 前言 在迭代图床应用时,需要用到图片压缩,在之前分享了使用 UPNG.js ...
- 基于rk3588----i2c驱动框架学习(2)-总线驱动 algorithm 分析
rk3588 i2c algorithm 分析 来了来了,上次分析完i2c的驱动框架 今天我们就看看i2c的algorithm是如何实现的 static const struct i2c_algori ...
- MVC架构设计浅析(WEB网页开发)
MVC架构设计浅析 杨传伟 (石家庄铁道大学信息科学与技术学院,河北省,石家庄市,050043) 摘 要:本文以图书管理系统为案例(当前主流框架SpringMVC的原理来分析MVC的设计理念等),深入 ...
- MySQL检索和过滤数据
注意 多条SQL语句必须以分号(:)分隔: SQL语句不区分大小写: 在处理SQL语句时,其中所有空格都被忽略: 当选择多个列是,一定要在列名之间加上逗号,但最后一个列名后不加. SELECT语句 检 ...
- #动态规划,组合计数,树状数组,前缀和#F 简单计数题&K 最简单的题
先膜两位出题人 F 简单计数题 题目 有\(n\)个活动,预约期有\(k\)天,第\(j\)天YC可以获得\(a_j(1\leq a_j\leq n)\)张预约券, 他会在\(n\)个活动中等概率选择 ...