使用Windbg分析从系统应用程序日志中找到的系统自动生成的dump文件去排查问题

目录

1、尝试将Windbg附加到目标进程上进行动态调试,但Windbg并没有捕获到

2、在系统应用程序日志中找到了系统在程序发生异常时自动生成的dump文件

2.1、查看应用程序日志的入口

2.2、在应用程序日志中找到系统自动生成的dump文件

3、使用Windbg静态分析dump文件

3.1、找到函数调用堆栈中相关模块的pdb文件,将pdb文件路径设置到Windbg中

3.2、查看详细的函数调用堆栈,对照着C++源码进行分析

4、总结


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具案例集锦(专栏文章正在更新中...)https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html       近日某个用户反馈,在其Win10的电脑上运行我们的软件,会频繁地出现崩溃闪退的情况,系统弹出程序已经停止运行的提示。我们尝试将Windbg附加到目标进程上分析,但Windbg并没有感知到,后来查看系统中应用程序日志找到系统自动生成的dump文件,然后分析这个dump文件才排查出问题。本文详细讲解这个问题的完整排查过程。

1、尝试将Windbg附加到目标进程上进行动态调试,但Windbg并没有捕获到

       用户反馈,在其Win10的电脑上运行我们的软件,会频繁地出现崩溃闪退问题,系统会弹出程序已经停止运行的提示,如下所示:

程序中安装的异常捕获模块没有感知到崩溃,没有生成包含异常上下文的dump文件。

       既然没有生成dump文件,那我们就尝试将Windbg附加到目标进程上进行动态调试,看看程序发声异常时Windbg能否捕捉到。于是让用户在启动程序时将Windbg附加到程序上,然后按照之前的问题场景去复现问题,一般使用Windbg动态调试时如果程序发声异常,Windbg都会感知到并中断下来,这样就能地问题进行分析了。

       但本问题有点不太一样,复现问题时Windbg并没有第一时间感知到,系统立即弹出了程序已经停止运行的提示。弹出该提示窗口时,Windbg也被冻结住了,没法进行操作了。这种场景还是第一次遇到,很是奇怪!

2、在系统应用程序日志中找到了系统在程序发生异常时自动生成的dump文件

        在日常分析软件异常崩溃问题时,基本都是使用Windbg分析的,要么使用Windbg静态分析dump文件,要么将Windbg附加到进程上进行动态调试。但目前这个问题,静态分析和动态调试都行不通,这就比较棘手了!后来想到,我们可以到系统的应用程序日志中查看一下,看看能不能找到一些线索。

2.1、查看应用程序日志的入口

       我们通过远程软件远程到用户的电脑上,在Win10系统的桌面上,右键点击“此电脑”,在弹出的右键菜单中点击“管理”菜单项,如下所示:

打开计算机管理窗口后,在系统工具节点下,展开事件查看器节点,在该节点下继续展开Windows日志节点,然后点击应用程序节点,这样右边就显示应用程序相关的系统日志了,如下所示:

        一般程序在发生异常时,系统感知到,会自动生成与之相关的日志。于是按照程序出问题时的时间点,在应用程序日志列表中找对应时间点的日志记录。出问题的时间点大概为2023/07/28 14:55,在应用程序日志列表中果然找到了这个时间的日志记录,如上所示。

2.2、在应用程序日志中找到系统自动生成的dump文件

        于是点击上述时间点的记录,在下方的详细信息中看到了问题的相关描述:

错误存储段 ,类型 0
事件名称: BEX
响应: 不可用
Cab Id: 0

问题签名:
P1: XXXXXXX.exe(哈哈,这个地方把程序名称做匿名处理)
P2: 7.0.0.3
P3: 648a1cec
P4: ucrtbase.dll
P5: 10.0.10586.0
P6: 5632d166
P7: 00083472
P8: c0000409
P9: 00000005
P10: 

附加文件:
C:\Users\Kvs\AppData\Local\Temp\WERF6BC.tmp.WERInternalMetadata.xml
C:\Users\Kvs\AppData\Local\Temp\WER53E1.tmp.appcompat.txt
C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_XXXXXXX.exe_a57edd93ecda26986177f6523e6d19d6506eb2_d05b1441_cab_15ff59bc\memory.hdmp
C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_XXXXXXX.exe_a57edd93ecda26986177f6523e6d19d6506eb2_d05b1441_cab_15ff59bc\triagedump.dmp
WERGenerationLog.txt

可在此处获取这些文件:
C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_XXXXXXX.exe_a57edd93ecda26986177f6523e6d19d6506eb2_d05b1441_cab_15ff59bc

分析符号: 
重新检查解决方案: 0
报告 Id: 08632728-2da3-493f-a30c-ffd617076fc3
报告状态: 96
哈希存储段: 

在日志描述信息中,首先看到发生的段错误,然后看到了系统自动生成的dump文件的完整路径:

C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_XXXXXXX.exe_a57edd93ecda26986177f6523e6d19d6506eb2_d05b1441_cab_15ff59bc\triagedump.dmp

然后到这个路径中将dump文件拷贝出来。这个应该是系统在检测到程序异常时自动生成的,应该是程序发生异常时包含异常上下文信息的dump文件,使用Windbg静态分析这个dump文件应该就能分析出问题的。

3、使用Windbg静态分析dump文件

        使用Windbg打开dump文件,先输入.ecxr命令切换到发生异常的那个线程中,然后输入kn命令查看该线程的函数调用堆栈,如下所示:

这个函数调用堆栈中看不到具体的函数名和代码的行号,是因为没有加载函数调用堆栈中模块的pdb符号文件的原因。

3.1、找到函数调用堆栈中相关模块的pdb文件,将pdb文件路径设置到Windbg中

        从当前的函数调用堆栈中,可以看到涉及到三个模块:xxlogdll.dll、xxxpsdll.dll和microblogdll.dll,所以我们需要去拿这三个模块的pdb符号文件。使用lm命令查看这三个模块二进制文件的时间戳,通过时间戳到文件服务器上去找pdb符号文件。以microblogdll.dll为例,查看该模块信息的命令为:lm vm microblogdll*,打印出来的模块信息如下:

从图中可以看出,当前的microblogdll.dll文件的时间戳(生成时间)为2023年06月13日09时56分21秒,于是以这个时间点,到文件服务器上找到对应的文件夹,找到对应时间点的pdb符号文件。

        将上述三个模块的pdb符号文件找到,统一拷贝到桌面路径C:\Users\Administrator\Desktop\pdbdir中,然后将pdb文件路径设置到Windbg中,设置的路径如下所示:

C:\Users\Administrator\Desktop\pdbdir;srv*f:\mss0616*http://msdl.microsoft.com/download/symbols
其中,C:\Users\Administrator\Desktop\pdbdir是业务库的pdb符号文件路径;

srv*f:\mss0616*http://msdl.microsoft.com/download/symbols为微软系统库pdb在线下载服务器地址,其中http://msdl.microsoft.com/download/symbols是在线下载服务器地址,f:\mss0616为从在线服务器上下载pdb文件的临时保存地址。

        之所以要设置Windows系统库的pdb在线下载服务器地址,是因为上述函数调用堆栈中包含系统库的模块ucrtbase.dll,我们要查看系统模块中的具体函数调用。有时如果能看到系统模块中的具体函数调用,能更有利于我们分析问题。

3.2、查看详细的函数调用堆栈,对照着C++源码进行分析

        加载pdb文件后,就能看到完整的函数调用堆栈了(能看到具体的函数名及C++代码的行号),如下所示:

从最上面调用的系统库的接口ucrtbase!_invalid_parameter来看,是程序中产生了无效的参数,无效参数引发了程序异常。再沿着函数调用堆栈向上看,是调用C函数vsnprintf函数去格式化数据引发的无效参数,当然肯定不是系统C函数vsnprintf中有问题。还要继续向上看,上面几个是打印日志的接口,然后继续向上,最终找到了调用打印日志接口的上层函数lohttp::CloHttp::OnHttpStackCb,其相关代码片如下:

上述代码中,要将一个char型buffer中的字符串作为日志打印出来,调用的是MiCROBLOG_LOG接口,使用的格式化符%s,要待格式化的参数p,应该也是吻合的,这里似乎并没有问题。如果是有问题,则可能是p指向的内存中的数据有问题,引发底层函数格式化时产生了异常。

       这个代码片段位于组件组维护的模块中,于是将上述函数调用堆栈及相关信息发给组件组的同事,让他们继续排查。其实这个地方有个简单的规避方法,直接在lohttp::CloHttp::OnHttpStackCb函数中将调用MiCROBLOG_LOG接口的那行代码注释掉即可。但这只是规避的办法,还是要搞清楚为什么会引发崩溃的。

4、总结

       这个问题现象比较少见,所以在此详细记录一下。一般情况下,将Windbg附加到进程上进行动态调试时,如果程序发生异常,Windbg应该能感知到并中断下来。结果这个问题中,直接弹出程序停止运行的系统提示框,Windbg并没有感知到。遇到这类情况时,可以尝试到系统的应用程序日志中查看相关记录,可能能找到程序发生异常时系统自动生成的包含异常上下文的dump文件,然后使用Windbg静态分析该dump文件就能分析出问题了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/52922.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysql的锁

加锁的目的 对数据加锁是为了解决事务的隔离性问题,让事务之前相互不影响,每个事务进行操作的时候都必须先加上一把锁,防止其他事务同时操作数据。 事务的属性 (ACID) 原子性 一致性 隔离性 持久性 事务的隔离级别 锁…

大数据课程D4——hadoop的YARN

文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解YARN的概念和结构; ⚪ 掌握YARN的资源调度流程; ⚪ 了解Hadoop支持的资源调度器:FIFO、Capacity、Fair; ⚪ 掌握YA…

jenkins自定义邮件发送人姓名

jenkins发送邮件的时候发送人姓名默认的&#xff0c;如果要自定义发件人姓名&#xff0c;只需要修改如下信息即可&#xff1a; 系统管理-system-Jenkins Location下的系统管理员邮件地址 格式为&#xff1a;自定义姓名<邮件地址>

三分钟白话RocketMQ系列—— 核心概念

目录 关键字摘要 Q1&#xff1a;RocketMQ是什么&#xff1f; Q2: 作为消息中间件&#xff0c;RocketMQ和kafka有什么区别&#xff1f; Q3: RocketMQ的基本架构是怎样的&#xff1f; Q4&#xff1a;RocketMQ有哪些核心概念&#xff1f; 总结 RocketMQ是一个开源的分布式消…

测试|测试分类

测试|测试分类 文章目录 测试|测试分类1.按照测试对象分类&#xff08;部分掌握&#xff09;2.是否查看代码&#xff1a;黑盒、白盒灰盒测试3.按开发阶段分&#xff1a;单元、集成、系统及验收测试4.按实施组织分&#xff1a;α、β、第三方测试5.按是否运行代码&#xff1a;静…

SpringMVC程序开发

1.什么是Spring MVC? Spring Web MVC是基于Servlet API构建的原始的Web框架&#xff0c;从一开始是就包含在Spring框架中。它的正式名称“Spring Web MVC"来自其源模板的名称&#xff08;Spring-webmvc)&#xff0c;但通常被称为“Spring MVC" 从上述的定义我们可…

Unity游戏源码分享-ARPG游戏Darklight.rar

Unity游戏源码分享-ARPG游戏Darklight.rar 玩法 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88105464

Android Studio 的版本控制Git

Android Studio 的版本控制Git。 Git 是最流行的版本控制工具&#xff0c;本文介绍其在安卓开发环境Android Studio下的使用。 本文参考链接是&#xff1a;https://learntodroid.com/how-to-use-git-and-github-in-android-studio/ 一&#xff1a;Android Studio 中设置Git …

Flowable-服务-微服务任务

目录 定义图形标记XML内容界面操作 定义 Sc 任务不是 BPMN 2.0 规范定义的官方任务&#xff0c;在 Flowable 中&#xff0c;Sc 任务是作为一种特殊的服务 任务来实现的&#xff0c;主要调用springcloud的微服务使用。 图形标记 由于 Sc 任务不是 BPMN 2.0 规范的“官方”任务…

在腾讯云服务器OpenCLoudOS系统中安装mysql(有图详解)

1. 创建MySQL安装目录 mkdir -p app/soft//mysql 2. 进入MySQL安装目录&#xff0c;下载&#xff0c;安装 cd /app/soft/mysql/ wget http://dev.mysql.com/get/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar 得到安装包&#xff1a; 解压安装包&#xff1a; 查看系统是否自带…

ts一些常用符号

非空断言操作符(!) 具体是指在上下文中当类型检查器无法断定类型时&#xff0c;一个新的后缀表达式操作符 ! 可以用于断言操作对象是非 null 和非 undefined 类型。具体而言&#xff0c;x! 将从 x 值域中排除 null 和 undefined 。 1. 赋值时忽略 undefined 和 null function…

JVM源码剖析之JIT工作流程

版本信息&#xff1a; jdk版本&#xff1a;jdk8u40思想至上 Hotspot中执行引擎分为解释器、JIT及时编译器&#xff0c;上篇文章描述到解释器过度到JIT的条件。JVM源码剖析之达到什么条件进行JIT优化 这篇文章大致讲述JIT的编译过程。在JDK中javac和JIT两部分跟编译原理挂钩&a…

游游的排列构造

示例1 输入 5 2 输出 3 1 5 2 4 示例2 输入 5 3 输出 2 1 4 3 5 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N1e55; int n,k; int main(){scanf("%d%d",&n,&k);int xn-k1;int yn-k;int f1;for(int i1;i&l…

【前端】javascript+html+css 家具销售网站(代码+报告)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

工业RFID读写器在食品饮料加工生产的应用!

当前食品饮料加工行业快速发展&#xff0c;得益于科技的应用&#xff0c;科技不仅提高了生产效率&#xff0c;还提升了食品生产质量和食品安全水平。其中&#xff0c;RFID技术在食品饮料行业中的应用对于加工生产帮助很大&#xff0c;RFID技术未来在食品饮料行业仍有巨大的潜力…

Mac 定时重启 TouchBar 脚本(缓解闪烁问题)

背景 Mac 笔记本 TouchBar 是真的脆啊&#xff0c;合盖使用一段时间就废了&#xff0c;右侧一直闪烁简直亮瞎眼 &#x1f602; 经过观察&#xff0c;总结出闪烁规律如下&#xff1a; 工作状态&#xff1a;不断操作电脑时&#xff0c;触控栏处于工作状态&#xff0c;几乎不闪…

明晚直播:可重构计算芯片的AI创新应用分享!

大模型技术的不断升级及应用落地&#xff0c;正在推动人工智能技术发展进入新的阶段&#xff0c;而智能化快速增长和发展的市场对芯片提出了更高的要求&#xff1a;高算力、高性能、灵活性、安全性。可重构计算区别于传统CPU、GPU&#xff0c;以指令驱动的串行执行方式&#xf…

5.开发DAO组件 -- Spring Data JPA

开发DAO组件 作用&#xff1a;用来访问数据库 持久化技术&#xff1a;Spring Data, JPA, Mybaits&#xff0c;jOOQ 等 Spring Boot为常见持久化技术提供了支持。 现在使用 Spring Data JPA Spring Data JPA 使用Spring Data JPA来访问数据库&#xff0c;需要再项目添加两个…

Python工具箱系列(三十九)

使用zlib对数据进行压缩 现实世界中&#xff0c;大量存在着对数据压缩的需求。为此&#xff0c;python内置了zlib压缩库&#xff0c;可以方便的对任意对象进行压缩。 下述代码演示了对字符串进行压缩&#xff1a; import zlib# 压缩一段中文 originstr 神龟虽寿&#xff0c…

Mysql触发器

1.触发器 触发器是与表有关的数据库对象&#xff0c;指在 insert / update / delete 之前或之后&#xff0c;触发并执行触发器中定义的SL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性&#xff0c;日志记录&#xff0c;数据校验等操作。 使用别名 OLD 和 …