基于开源CrashRpt与微软开源Detours技术深度改造的异常捕获库分享

目录

1、异常捕获模块概述

2、为什么需要异常捕获模块?

3、在有些异常的场景下是没有生成dump文件的

4、开源异常捕获库CrashRpt介绍

5、对开源库CrashRpt的改进


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html       最近有很多朋友问到异常捕获机制及开源异常捕获库的问题,今天有时间,就给大家说说异常捕获库相关的内容

1、异常捕获模块概述

       异常捕获模块是内置在程序中的,当程序发生异常,异常捕获模块感知(捕获)到,自动生成包含异常上下文的dump,文件,可能同时也会生成程序版本等信息的日志文件。事后,我们可以取来这些日志及dump文件去分析软件发生异常崩溃的原因。

       异常捕获模块一般是以函数回调的方式通知给主程序,此时主程序可以弹出相关的提示框,提示用户程序发生了异常崩溃,用户可以重新运行程序。程序中内置异常捕获模块,已经成为一种标配,大部分程序都会自带异常捕获模块。以PC版的微信为例,当微信发生崩溃时,其内置的异常捕获模块会捕获到异常并生成日志及dump文件,同时会弹出如下的发送错误报告的提示框:

提示框的下方会自动带上崩溃相关的文件,其中最后一个文件就是包含异常上下文信息的dump文件,点击确定则会将这些文件发送到腾讯远端的后台服务器上。腾讯后台的运维人员会收到通知,然后到服务器上将dump等文件下载下去分析。

       有些软件可能没有上传崩溃日志到服务器的功能,捕捉到异常时会自动将dump文件保存到指定的路径中,事后可以到该路径中取到对应的dump文件。如果客户机器上遇到崩溃,可以和客户联系,让客户帮忙从对应的路径中取来出dump文件发过去。

2、为什么需要异常捕获模块?

       在日常项目开发维护的过程中,会遇到这样那样的异常崩溃,分析这些异常崩溃最常用、最重要的途径就是事后分析异常发生时生成的dump文件。

       要分析软件异常崩溃,首先要有dump文件,那包含异常上下文信息的dump文件是如何生成的呢?以前我们讲过生成dump文件的三种方式:

1)通过内置的异常捕获模块,去捕获软件发生的异常崩溃,自动生成包含异常上下文的dump文件。这是生成dump文件最常用的方式。
2)可以在动态调试的Windbg中,使用.dump命令手动导出包含异常上下文信息的dump文件。为啥要导出dump文件呢?既然Windbg在动态调试,为啥不能直接分析呢?在条件允许的情况下可以直接在Windbg中分析,但一时半会分析不出来问题时或者不能长时间占用用户的电脑时,就需要导出dump文件,供事后分析了。
3)可以从Windows任务管理中导出dump文件。在任务管理器的进程列表中找到目标进程,右键点击,在弹出的右键菜单中点击导出转储文件即可。这种方式首先要求出问题的程序进程还存活着的(进程还在的),比如程序发生卡死、死循环或者程序弹出报错提示框时(弹出报错提示框时,如果不点击提示框中的按钮将提示框关闭掉,则程序进程还在的)。

其中,通过异常捕获模块去生成dump文件,是最常用的一种方式。事后分析dump文件,也是我们分析和排查软件异常崩溃问题最常用的方法。

       关于dump文件及生成方式的详细说明,可以查看我之前写的文章:

dump文件类型与dump文件生成方法详解icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/127991002       有人可能会说,遇到问题,我直接使用IDE去调试不就行了,我不需要什么dump文件的!如果这样说,只能说其处理异常问题的经验太有限了!因为有些问题可能是很难复现的,或者问题只在客户的环境中复现,这样也就无从去调试代码了。再就是程序中有多个模块,不同的模块由不同的开发组负责,如果程序崩溃在底层的模块中,还需要底层去调试代码。底层模块的开发人员需要搭建调试环境,然后使用附加到进程的方式去调试代码。

       如果在程序中安装了异常捕获模块,在程序发生异常时自动生成包含异常上下文的dump文件,我们直接将dump文件取来分析就好了,就不用老想着如何去复现问题了。直接使用Windbg静态分析dump文件,查看发生异常的那条汇编指令以及发生异常的函数调用堆栈,一般就能快速地定位问题了,可以有效地提高我们排查问题和解决问题的效率。

当然,并不是说有了dump文件,就一定不需要复现问题了。在个别情况下,通过分析dump文件很难排查出问题时,可以尝试去复现问题(找到复现问题的操作规律),找到问题发生的场景,这样可能去辅助分析问题的。所以有时候,为了排查分析问题,我们需要使用多种手段与方法的!


         在这里,给大家重点推荐一下我的几个热门畅销专栏:

专栏1:(该专栏订阅量已达到420多个,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!)

C++软件调试与异常排查从入门到精通系列文章汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据近几年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的实战问题分析实例,带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

专栏中的文章均是通过项目实战总结出来的(通过项目实战积累了大量的异常排查素材和案例),有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2: 

C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域的多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!

专栏3: 

开源组件及数据库技术icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html

以多年的开发实战为基础,分享一些开源组件及数据库技术!


3、在有些异常的场景下是没有生成dump文件的

       即便程序中安装了异常捕获模块,在某些异常的场景下,可能也是没有生成dump文件的。这里面是有多种原因的。

       首先,异常捕获模块不是万能的,只能捕捉(感知)到大部分的异常,但不能捕获所有的异常,这和异常捕获模块的捕获机制的缺陷有关。其次,可能在生成dump文件时产生了二次崩溃,生成的dump文件是空的。对于没有生成dump文件的场景,就只能尝试Windbg的动态调试了,将Windbg附加到目标进程上,和目标进程一起跑,一旦程序发生异常,作为正在调试的调试器Windbg,会第一时间感知到并中断下来,此时去查看函数调用堆栈去分析就好了。

       再者就是,程序只是发生了闪退,但程序没有发生异常崩溃。比如我们在项目中遇到的两个典型的场景,一个是在用开源库jsoncpp时错误地解析json串中的字段类型时,jsoncpp发现类型错误,就直接认为是致命的,直接调用abort接口将进程终止了。还有一个场景是,我们在使用开源库WebRTC时,当调用malloc动态申请内存失败时(可能是程序内存不足导致的申请失败),malloc返回NULL,WebRTC认为内存申请不到了,业务没法正常运行下去,认为这是致命的,程序没有继续活着的意义了,直接调用abort强行将进程终止了。

       对于这两种强行终止进程的场景,并没有发生C++上的异常,只是代码人为地终止了进程。从现象上看,程序直接闪退了(没了),给人一种程序发生异常崩溃导致程序闪退的感觉,其实程序并没有发生异常崩溃,是代码人为终止进程的。对于这种强行终止进程的场景,就需要使用Windbg动态调试了,将Windbg附加到目标进程上,和目标进程一起跑,C函数abort内部会产生一个特殊的异常,让让调试器Windbg中断下来,此时查看函数调用堆栈,就知道是调用了abort强行终止进程的,然后继续结合函数调用堆栈去分析问题了。

       对于使用开源jsoncpp和开源WebRTC遇到的强行终止进程的问题,具体细节可以去查看我之前写的文章:

C++程序中执行abort等操作导致没有生成dump文件的问题案例分析icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/129003869       此外,有时即使拿到了dump文件,可能也需要用Windbg进行动态调试的。比如从现有dump文件中分析不出问题时或者看到的函数调用堆栈不全或有问题,可以尝试使用Windbg进行动态调试。再比如,以前我们讲过,有时可能要查看相关变量的值,这些变量的值可能是排查问题的关键线索,但异常捕获模块生成的dump文件是小dump文件(比如几百KB或几MB,只保存了小部分内存信息),只能部分变量的值,有些变量的值是看不到的,但这些变量可能是分析问题的关键线索,这时也可以尝试使用Windbg进行动态调试,动态调试时可以看到所有变量的值。

       对于通过查看相关变量值去快速定位问题的案例,可以查看我的文章:
通过查看Windbg中变量值去定位C++软件异常问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125731044       对于很好复现的问题,使用Windbg动态调试很方便的,将Windbg挂到目标进程上,快速复现问题,Windbg感知到异常中断下来,就可以立即分析了。对于不好复现或者很难复现的问题,只能每次启动程序测试时都将Windbg挂上去,等待复现为止。

      关于何时使用Windbg静态分析与动态调试,可以查看我的文章:

何时使用Windbg静态分析?何时使用Windbg动态调试?icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131806819

4、开源异常捕获库CrashRpt介绍

       如何去设计异常捕获库呢?大家都会想到使用系统API函数SetUnhandledExceptionFilter去设置异常回调,当程序发生异常时就会调用设置的回调函数,然后在回调函数中调用API函数MiniDumpWriteDump去生成dump文件。但使用这种方式,缺陷很明显,很多异常捕获不到,可以选择开源的异常捕获库。

       常见的开源捕获库有CrashRpt和Google开源的CrashPad,今天我们来重点介绍一下CrashRpt。CrashRpt 是一个免费的、轻量级的开源错误报告库开源库,旨在拦截C++程序中的异常,收集有关崩溃的技术信息并通过互联网向软件供应商发送错误报告,用于 Windows C++应用程序中。

1)CrashRpt 可以处理主线程和用户模式程序的所有工作线程中的异常:SEH 异常(Structured Exception Handling 结构化异常处理)、未处理C++类型异常、信号和 CRT (C运行时)错误。在 CrashRpt 可以处理的错误类型中,有:NULL 指针分配、访问冲突、无限递归、堆栈溢出、内存耗尽等。
2)CrashRpt能生成错误报告,包括小型崩溃转储minidump文件、可扩展的崩溃描述XML文件、应用程序自定义的文件(如程序日志文件)等。

5、对开源库CrashRpt的改进

       CrashRpt对多线程支持的不好,导致很多异常捕获不到。另外,CrashRpt在捕获到异常时,会自动自动截屏、录制视频和发送邮件,这些功能其实是什么用处的,直接把它们裁剪掉。对于发送邮件,CrashRpt中是直接使用socket实现的,其稳定性不太好,如果需要用到这个功能,可以使用开源库libcurl,libcurl中支持POP3和SMTP邮件协议。

       为了解决CrashRpt很多异常捕获不到的问题,我们首先添加了对多线程的支持,然后引入了微软的Detours技术,有效地提高了异常捕获的效率,基本可以捕获90%以上的异常。捕获到异常后,就会生成dump文件,事后使用Windbg去分析dump文件即可。对于没捕捉到的异常的场景,则需要使用使用Windbg进行动态调试了,上面这些场景我也详细讲到了。

如果要获取到该改进的异常捕获库,可以联系微信kvsthingking

       关于如何使用Windbg去静态分析dump文件,可以查看我的文章:
使用Windbg分析dump文件的一般步骤及要点详解icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/130873143      关于如何使用Windbg去动态调试目标进程,可以查看我的文章:

使用Windbg调试目标进程的一般步骤及要点详解icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/135484906

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

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

相关文章

NX二次开发UF_VEC(向量运算)常用函数

目录 一、概述 二、函数的介绍 2.1 UF_VEC3_add(两向量相加) 2.2 UF_VEC3_affine_comb(未缩放和缩放后的和) 2.3 UF_VEC3_angle_between(使用第三个向量确定连个向量的夹角) 2.4 UF_VEC3_ask_perpendicu…

【状态机dp 动态规划】100290. 使矩阵满足条件的最少操作次数

本文涉及知识点 动态规划汇总 状态机dp LeetCode100290. 使矩阵满足条件的最少操作次数 给你一个大小为 m x n 的二维矩形 grid 。每次 操作 中,你可以将 任一 格子的值修改为 任意 非负整数。完成所有操作后,你需要确保每个格子 grid[i][j] 的值满足…

人人可拥有刘强东同款数字人分身!

每个人都可以拥有东哥同款数字人分身直播间进行直播带货,怎样克隆自己的数字人形象? 青否数字人克隆源码的克隆效果媲美真人: 仅需将真人录制的2-6分钟视频上传至克隆端后台,系统便会自动启动自动克隆。3-5小时后,即可…

LR系统关联错误

报错提示: 開日:Vuser艳湾辫触?mdrv.dat函欢?CCI聞/珞涓ECCIDebug剧涓?off?璀:十cciext.dll钙筑婧?ExtPerProcessInitialize踩整伴叔璇?-19797:缩跨v涓?璋幂椹下动清鳄"叶璐…

Oracle交换分区测试

1、用exchange分区表减少初始化过程中对业务中断的影响 2、创建分区表 create table t_p (id number,name varchar2(30),addr varchar2(50)) partition by range(id) (partition p1 values less than(10), partition p2 values less than(20), partition p3 values less …

免费听音乐,下载音乐mp3,mp4,歌词的网站分享(2024-04-22)

亲测!!! 1、音乐客 免费听和免费下载 经典老歌 - 音乐客音乐客,yinyueke.net,免费音乐,免费在线音乐播放器,免费下载音乐,音乐,播放器,下载,播放,DJ,免费,mp3,高音质,…

A4云打印仅需5分/页?云打印多少钱?云打印怎么收费?

随着互联网技术的发展,越来越多的同学在打印资料的时候都开始转向线上,转向云打印服务了。云打印服务不仅可以给我们节省很多时间,价格方面较打印店也更有优势。那么云打印多少钱?云打印怎么收费?今天小易就带大家来了…

git 某个分支代码回滚到某次push的步骤

切换到需要操作的分支 git checkout 分支名称 命令: git log 获取代码的提交记录,按小写q退出当前命令对话。 获取某次提交或者合并的hash值:如:2cf0f19ab21aa62f5ebffa5f08caed3f63842346 使用reset命令对当前分支进行回退到某…

sklearn【AUC-ROC】原理,以及绘制ROC曲线!

一、AUC-ROC 介绍 在分类任务中,特别是当数据集中的类别分布不平衡时,评估模型的性能变得尤为重要。AUC-ROC(Area Under the Receiver Operating Characteristic Curve,受试者工作特征曲线下的面积)是一种有效的评估指…

Rancher 应用商店离线环境使用

前言 Rancher (v2.5 ) 应用商店可以方便的安装 Helm3 构建的应用,并且支持私有 helm 应用仓库,方便了内网离线环境下的使用。本文以内网离线环境为前提、以 MySQL 5.7.43 版本为应用举例,从零开始手把手教你如何制作并应用。 1、环境准备 1.…

自然资源领域-点状用地和乡村振兴产业用地办理指引

自然资源领域-点状用地和乡村振兴产业用地办理指引(广州借鉴) “点状供地”是相对于传统的“片状供地”而言的一种新型供地方式,是办理项目建设用地报批及供地手续的关键环节,也是项目开发建设的重要依据。 通俗说:“…

半导体制造工艺之分类浅述

半导体制造工艺分为逻辑制程(也叫逻辑工艺)和特殊制程(也叫特色工艺)。 1、逻辑工艺概述 随着集成电路行业沿着摩尔定律不断发展,晶体管数量增加的同时,工艺节点不断缩小。先进逻辑工艺是相对的概念,2005年全球先进逻辑工艺的工艺节点在65/55纳米,现在则变为3纳米。中…

AOP容器面向切面编程(动态代理)

aop面向切面编程 动态代理方式进行 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency> 面向特定的方法进行编程 统计方法的执行耗时&#xff0c;要执行的是哪个方…

Vue前端框架如何调用天聚数行API?

Vue是一个业内优秀的前端解决方案&#xff0c;采用了最新流行的MVVM框架模式&#xff0c;深受web前端开发者的喜爱&#xff0c;在相关开发者社区也一直都是热门交流话题。那么&#xff0c;如何通过Vue调用天行数据的API接口呢&#xff0c;下面就具体给大家示例。 vue采用的是数…

【Interconnection Networks 互连网络】Flattened Butterfly 扁平蝶形拓扑

Flattened Butterfly 扁平蝶形拓扑 1. 传统蝶形网络 Butterfly Topology2. 扁平蝶形拓扑 Flattened Butterfly3.On-Chip Flattened Butterfly 扁平蝶形拓扑应用于片上网络 Flattened Butterfly 扁平蝶形拓扑 扁平蝶形拓扑是一种经济高效的拓扑&#xff0c;适用于高基数路由器…

护眼落地灯哪个牌子好?落地灯十大知名品牌

一款优异的落地灯不只有照明的作用&#xff0c;更有装修作用。只不过&#xff0c;市面上的落地灯产品很多&#xff0c;质量良莠不齐&#xff0c;很多人不知道怎么挑选是好。小编的主张是从品牌下手&#xff0c;挑选口碑上佳的品牌落地灯产品。若问护眼落地灯哪个牌子好&#xf…

【学习】人工智能在软件测试中的作用有哪些

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到各个领域&#xff0c;并发挥着不可或缺的作用。其中&#xff0c;在软件测试方面&#xff0c;AI的应用也愈发普遍。本文将探讨人工智能在软件测试领域的关键作用以及其带来的积极影响。 一、提升测…

0.5W 3KVDC 隔离单、双输出 DC/DC 电源模块——TPV-W5 3.3V, 5V,12V 15V系列

TPV-W5系列提供正负双输出和单输出&#xff0c;工业级环境温度&#xff0c;用于PCB安装的国际标准结构。此系列产品小巧&#xff0c;效率高&#xff0c;低输出纹波及能承受3000V以上的耐压&#xff0c;用于需要正负电压或单输出和高隔离电压的场合。封装有SIP和DIP可选。

三、SpringBoot整合MyBatis

本章节主要描述MyBatis的整合&#xff0c;以及使用mybatis-generator-maven-plugin生成代码骨架&#xff0c;源码&#xff1a; jun/learn-springboot - Gitee.com 一、首先建数据库 本示例用的是MySQL8.0.23&#xff0c;建表t_goods、t_orders&#xff0c;略... 二、goods模块…

李廉洋:4.22现货黄金,WTI原油晚间行情走势分析及策略。

今年&#xff0c;全球金融市场正遭遇一股他们未曾预料到的力量&#xff1a;强势美元卷土重来&#xff0c;而且似乎将持续下去。根据美国商品期货交易委员会(CFTC)的数据&#xff0c;一项衡量交易员情绪的流行指标在今年年初指向看跌&#xff0c;但现在已转变为2019年以来最看涨…