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 ...
随机推荐
- tomcat中虚拟主机以及web应用程序的配置
一:新建虚拟主机 1. 在tomcat里新建文件夹myapps,在里面添加ROOT文件,放入网站的首页文件 新建文本文档,输入你想要的内容我这里的内容是TOM.AI,把文本文档的名字改成index.h ...
- uni组件传值注意
目录介绍 01.组件传值遇到坑 02.父组件传值给子组件 03.子组件传值给父组件 01.组件传值遇到坑 子组件给父组件传值注意点 注意子组件触发事件定义的方法,首先在父组件中需要绑定子组件内部对应事 ...
- JS数据扁平化
最近找到了一些数据扁平化的精品文章,这里分享给大家,希望对大家有所帮助 什么是扁平化 数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组. 举个例子,假设有 ...
- APP探索之iAPP
APP探索之iAPP 1.基本作用 iAPP是一个手机上的应用,可以用于快速设计手机应用,基本免费.使用的语言好像是自创的脚本语言.无聊时可以用iAPP做一些简单的训练,可以练习文件和数据的操作.对于 ...
- linux安装crontab
1.查看是否安装 rpm -qa | grep cron #没有输出内容说明没有安装 2.安装 yum -y install vixie-cron #cron 的主程序 yum -y install ...
- MemfireCloud让静态托管页面动起来!
静态托管 我们最常接触到的静态托管是github pages,它的常见工作模式是在github上创建一个仓库,使用hexo类的工具初始化仓库,编写markdown文件,生成静态页面,推送到github ...
- IDEA 2018 激活(UMTIMATE)
IDEA延长使用期限 这是我的软件About,2018版本,延期至2089. 先下载压缩包解压后得到jetbrains-agent.jar. 下载页面:https://zhile.io/2018/08 ...
- 04 jQuery遍历器
04 jQuery遍历器 如果jQuery一次性选择了很多元素节点. 而我们又希望能拿到每一个元素中的相关信息. 此时可以考虑用jQuery的遍历器来完成对元素的循环遍历. 例如: <!DOCT ...
- Go 语言输出文本函数详解
Go语言拥有三个用于输出文本的函数: Print() Println() Printf() Print() 函数以其默认格式打印其参数. 示例 打印 i 和 j 的值: package main im ...
- Qt5自带的日志功能,将日志输出到文件
#include "QtWidgetsApplication1.h" #include <QtWidgets/QApplication> #include <Qt ...