根据发生异常的汇编指令以及函数调用堆栈,从内存的角度出发,估计出问题的可能原因,确定排查方向,快速定位C++软件问题

news2024/10/22 13:23:17

目录

1、前言

2、初步分析dump文件

3、加载更多模块的pdb文件,可能能看到更多行的函数调用堆栈

4、从内存的角度去看,估计是访问了野指针导致的,沿着这个怀疑的方向快速地定位了问题

5、最后


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(专栏文章已更新460多篇,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/140824370C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/category_2276111.html       最近在项目中遇到了一个崩溃问题,取来dump文件,用Windbg打开分析,查看函数调用堆栈,将堆栈对照着源码分析,并没有发现明显的问题,找不到问题排查的切入点或线索。后来查看发生异常的那条汇编指令,并对照着异常时函数调用堆栈中调用的函数,从内存的角度出发,大概估计出了可能的原因,确定了一个大致的方向,然后按照这个方向快速定位了问题本文分享一下这个问题的大概排查思路与过程,以供借鉴或参考。

1、前言

       当我们查看崩溃时的函数调用堆栈,如果最终崩溃在系统库或第三方开源库中,一般不是系统库或第三方开源库有问题,是上层的业务库有问题导致的。有时也会崩溃在项目中常用的通用库中,通用库可能用了好几年了,基本是不会发生崩溃的,所以问题一般也是发生在上层模块中,应该从上层模块入手进行排查。

       此外,C++软件中的异常或崩溃,大多都是与内存相关的,比如访问空指针或野指针、内存越界、内存泄漏、线程栈溢出、堆内存被破坏、内存不足等。所以我们分析问题时,尽量从内存的角度出发(C++软件异常大部分都是与内存相关的),尝试着估计原因,寻找线索,沿着估摸的方向去分析,可能很快就能定位问题。

       今天讲的这个实例,就是从内存的角度去看,根据发生异常的那条汇编指令以及异常时的函数调用堆栈,从内存的角度出发,估计可能是访问了野指针(指针指向的内存地址已经被释放了)引发的,然后沿着这个方向分析,快速地定位了这个问题。

2、初步分析dump文件

       程序崩溃时,程序中安装的异常捕获模块感知到了,并自动生成了dump文件。取来了dump文件,用Windbg打开,使用.ecxr命令切换到发生异常的那个线程,然后使用kn命令查看函数调用堆栈。根据堆栈中涉及到的模块,确定要去拿哪些模块的pdb文件,使用lm查看模块的时间戳,根据时间戳到保存软件版本的文件服务器上找到pdb文件(我们的软件版本统一放到文件服务器上保存的)。

        将pdb文件的路径设置到Windbg中,然后输入.ecxr命令切换到发生异常的线程:

当前发生的是0xc0000005内存访问违例的异常,即访问了不该访问的内存。于是查看发生崩溃的那条汇编指令,如上所示,这条汇编指令中访问了0x352ba8f0,是访问这个内存地址产生的异常,但这个内存地址没有明显的异常。0x352ba8f0既不是访问空指针时的很小的内存地址(地址位于0-64KB范围的,禁止访问),也不是很大的内核态内存地址(用户态的代码禁止访问内核态的地址)所以从这条崩溃的汇编指令中没有看出明显的异常。


        在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:该精品技术专栏的订阅量已达到530多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)

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

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

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2:(本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,订阅量已达170多个,专栏文章已经更新到460多篇,持续更新中...)

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

以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、数据结构与算法、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。

专栏3:  

C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/131405795

常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!

专栏4:   

VC++常用功能开发汇总(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/124272585

将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。

专栏5: 

C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/category_12695902.html

根据多年C++软件开发实践,详细地总结了C/C++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


3、加载更多模块的pdb文件,可能能看到更多行的函数调用堆栈

       在没加载pdb文件或者加载部分pdb文件时,可能看到的函数调用堆栈比较少,但加载更多的pdb文件之后,可能可以看到更多行的函数调用堆栈这样可能更有利于问题的排查。这个现象,我们在项目中多次遇到了,比如设置系统库的pdb在线下载地址(微软系统库pdb文件下载服务器)后,能看到更多行的函数调用堆栈。

       本案例中也遇到了,最开始只取了部分模块的pdb文件,只能看到6行函数调用堆栈,如下所示:

图中的config.dll模块没有加载pdb文件,后来根据lm命令显示的时间戳:

到文件服务器上找来了对应时间点的pdb文件。在Windbg加载到这个pdb文件之后,使用kn命令重新查看函数调用堆栈:

明显看到,调用堆栈中多了很多行。行数越多越详细,越有利于问题的排查。

       此外,有时如果路径下有没有模块的二进制文件,对函数调用堆栈也有一定的影响,我们在项目中遇到过。

4、从内存的角度去看,估计是访问了野指针导致的,沿着这个怀疑的方向快速地定位了问题

       发生异常时的函数调用堆栈如下所示:

从堆栈的最上面可以看出,程序崩溃在directui.dll模块中。这个directui.dll库,我们用了很多年了,一直比较稳定。虽然最终崩溃在directui.dll库中,但一般问题都出在上层的模块中(应该从上层模块去入手排查),到上层模块config.dll中去查找原因。

       我们再来看崩溃的这条汇编指令:

汇编指令中访问了0x352ba8f0内存地址,产生了内存访问违例,但这个内存地址没有看出明显的异常。0x352ba8f0既不是访问空指针时的很小的内存地址(地址位于0-64KB范围的,禁止访问),也不是很大的内核态内存地址(用户态的代码禁止访问内核态的地址)。

       我们知道,很多内存访问违例的问题,可能是访问空指针或野指针触发的。访问空指针时,会访问很小的内存地址,地址位于0-64KB之内的内存地址是禁止访问的,会触发内存访问违例。访问野指针,就是访问已经释放的内存区域,一般也会触发内存访问违例,因为内存已经释放。

事实上,访问已经释放的内存,不一定会触发内存访问违例。这个要看系统的脸色,系统允许你访问,就不会引发访问违例;系统不允许你访问,就会触发访问违例。

       既然不是访问空指针引发的内存访问违例,那怀疑可能是访问了野指针导致的。崩溃的汇编指令位于directui库的CDuiImage::GetBits接口中,崩溃在访问当前CDuiImage类的数据成员产生的崩溃,所以当前这个CDuiImage对象有问题,而根据崩溃时的函数调用堆栈:

这个CDuiImage对象是依附在上层的CCfgServerContainDlg窗口类对象中的,所以应该是这个CCfgServerContainDlg窗口类对象有问题。于是根据函数调用堆栈,去查看C++源码,照着访问野指针的思路去阅读与问题相关的源码上下文。最后看下来发现,果然是野指针导致的。本案例主要讲述排查思路、方法及相关细节要点,具体问题代码的排查过程就不在此展开了。

       正是沿着访问野指针的思路去排查代码,快速地定位了问题,所以排查方向很重要,比漫无目的地查看源码要好很多。所以在遇到问题时,我们可以根据现有的信息及现象,估计出一个或多个可能的排查方向,然后沿着这些方向去逐一的排查。

5、最后

       引发本案例问题的原因,并不复杂,但排查的思路和过程却有一定的参考价值。在排查过程中涉及到的一些细节和知识点是值得关注和推敲的。所以在此将相关内容分享出来,以供大家借鉴或参考。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【安当产品应用案例100集】024-BYOE及BYOK在IaaS场景中的应用

在云计算环境中,尤其是涉及到敏感数据时,企业用户可能会选择自带加密工具或密钥(即BYOE或BYOK),以确保数据在传输和存储过程中的安全性。这种方式可以防止云服务提供商访问或泄露加密数据,增强数据保护。 …

离散数学 第二讲 特殊集合和集合间关系 笔记 [电子科大]王丽杰

1.2 特殊集合与集合间关系 空集 不含任何元素的集合叫做空集(empty set),记作∅. 空集可以符号化为 ∅ { x ∣ x ≠ x } ∅ \{ x|x ≠ x\} ∅{x∣xx} . 空集是绝对唯一的。 全集 针对一个具体范围,我们考虑的所有对象的集合叫做全集(universal se…

基于springboot招聘信息管理系统设计与实现(源码+定制+开发)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

视频美颜平台是如何搭建的?基于直播美颜SDK源码的开发技术详解

今天,笔者将详细讲解如何基于直播美颜SDK源码搭建视频美颜平台的技术路径。 一、理解视频美颜技术 视频美颜技术主要通过图像处理算法对视频流进行实时处理,包括肤色优化、瑕疵修复、面部特征增强等。实现这一目标需要高效的图像处理算法和稳定的实时渲…

5个最流行的图像嵌入模型对比

最近需要研究图像相似性搜索。我想知道基于架构训练方法的嵌入之间是否存在差异。但是,很少有博客比较几种模型之间的嵌入。因此,在这篇博客中,我将使用 Flickr 数据集 [6] 比较 EfficientNet [1]、ViT [2]、DINO-v2 [3]、CLIP [4] 和 BLIP-2…

Matlab软件进行金融时间序列数据的描述性统计代码

1、数据S&P500的收盘价格,return100*log(pt/pt-1) 方法1:用python代码 import numpy as np import pandas as pddef calculate_log_returns(prices):"""计算价格序列的对数收益率。参数:prices (numpy.array): 价格序列。返回:log_…

Mongodb基础用法【总结】

关系型数据库和非关系型数据库的区别 关系型数据库 1.在关系型数据库中,数据都是存储在表中的,对存储的内容有严格的要求 2.因为我们在创建表的时候久已经规定了表中的字段 存储的数据类型 是否为空 唯一标识等规则 3.由于操作的都是结构化的数据&#…

家政小程序搭建,数字化市场发展下的意义

家政服务行业作为当下社会生活中不可或缺的行业,需求量在逐渐增加,行业发展也趋向多样化。 随着数字化的浪潮,家政行业逐渐向数字化、智能化升级发展,推动行业高质量发展,迎合现代化发展趋势,这一转型为行…

83.【C语言】数据结构之顺序表的尾部插入和删除

目录 3.操作顺序表 2."伪"插入顺序表的元素 分析尾部插入函数SLPushBack 代码示例 SeqList.h main.c free(指针)出错的几种可能的原因 3."伪"删除顺序表元素 2.分析尾部删除函数SLPopBack 代码示例 错误检查 两种解决办法 1.判断size是否为负…

004-按照指定功能模块名称分组

按照指定功能模块名称分组 一、说明1.现在有一个需求:2.具体做法 二、代码案例三、效果展示 一、说明 1.现在有一个需求: 需要把一个功能模块的几个功能点放在同一个文档目录下,这几个功能点分布在不同的 Controller 2.具体做法 需要把他…

如何将markdown文件转换为pdf

最近笔者在用vscode写markdown,但是提交时往往需要交pdf。所以就涉及到如何将markdown转化为pdf格式。 首先,需要在vscode上安装插件 markdown Preview Enhanced 之后在vscode的右上角即可看到下述图标,点击,vscode右半面就会显示…

C++数据结构-图的存储及邻接矩阵的代码实现

1. 什么是图 图论(graph theory) 是数学的一个分支,它以 图 为研究的对象。 图论本身是应用数学的一部分,历史上图论曾经被很多数学家各自独立建立过。关于图论的最早文字记载最早出现在欧拉 1736 年的论著中,也就是…

2024年有哪些开放式耳机值得入手?开放式耳机排行榜10强

随着技术的不断进步与消费者需求的日益多样化,开放式耳机凭借其独特的优势——如保持对周围环境的感知、减少对耳道的压力等,逐渐成为市场上的一大热点。尤其是在健康意识不断提升的今天,开放式耳机不仅为音乐爱好者提供了全新的聆听体验&…

【C++语言】全面掌握const的用法

一、const 需要怎么理解?? const修饰的变量不能够再作为左值,初始化完成之后,值不能被修改 1.1 C语言的const const 修饰的量,可以不用初始化,不叫常量,叫做常变量。 void main() {const int…

Windows git 配置

需要在git-bash的目录下,配置.ssh 的配置文件 要 .ssh 目录下的配置无法使用

Modbus TCP报错:Response length is only 0 bytes

问题描述: 使用modbus_tk库,通过Modbus tcp连接PLC时,python中的一个报错信息: Response length is only 0 bytes报错原因: 与Modbus TCP 服务端建立连接后没有断开,继续作为长连接使用,客户端…

一文掌握Cephadm部署Ceph存储集群

📚 博客主页: StevenZeng学堂 🎉 本文专栏: 一文读懂Kubernetes一文读懂Harbor云原生安全实战指南云原生存储实践指南 ❤️ 摘要:随着企业数据量的增长和存储需求的复杂化,Ceph因其高可扩展性和灵活性,能…

AI劳动力崛起:人将面临失业危机?

场景 第一眼看到这个网站的时候,AI员工官网(好像是部署在美国),我觉得很好奇,真的可以让AI替代人类完成工作吗?替代到什么程度呢?能以自然语言直接驱动吗? 正好手上在做爬虫项目&am…

HCIP-HarmonyOS Application Developer 习题(十六)

(判断)1、HiLink通过分布式软总线的方式连接所有设备,强能力设备可对弱能力设备进行设备虚拟化,将弱设备当做本机设备直接调用。 答案:错误 分析:HiLink 主要针对的是应用开发者与第三方设备开发者&#xf…

医院排队叫号系统

医院分诊排队叫号系统是一种广泛应用于服务行业的智能化管理系统,系统可有效地解决病人就诊时排队的无序、医生工作量的不平衡、就诊环境嘈杂等问题,它主要用于改善服务流程,提高服务效率,优化客户体验。这种系统通常包括以下几个…