访问0xdddddddd内存地址引发软件崩溃的实战问题排查

目录

1、问题描述

2、访问空指针或者野指针

3、C++程序中常见的异常内存值

4、0xdddddddd内存访问违例问题分析与排查

4.1、初步分析

4.2、CConfMeidaConfigDlg窗口类对象是何时被销毁的?

4.3、为啥会访问到已经释放内存的CConfMeidaConfigDlg类对象?

5、关于0xcdcdcdcd和0xfeeefeee异常值的排查案例

6、最后


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.htmlWindows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.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       在C++软件中访问了有问题的指针变量,可能会引发程序产生异常,比如访问了空指针和野指针,这也是操作指针错误最常见的原因。今天我们就来讲一个操作已经释放内存的野指针实例,本例中的问题指针有些特殊,释放内存后指针值变为0xdddddddd,和以往常见的异常值0xfeeefeee有所不同。本文将详细讲述一下这个问题的完整分析过程,以供大家借鉴或参考。

1、问题描述

       某天在调试某个功能时发现,在执行某个操作(为了方便说明问题,下文将该操作称作A操作)后再次执行该操作,程序就出现了短暂的卡死,然后出现了闪退。这个问题是必现的,于是用Visual Studio调试运行,按照复现的步骤复现了问题,弹出了如下的访问0xdddddddd异常内存地址的弹框:

对于32位程序,这个0xddddddddd地址属于内核态的内存地址,用户态的代码是禁止访问的,所以触发了内存访问违例,产生了崩溃。下面就详细讲述一下这一问题的排查过程。

2、访问空指针或者野指针

       在操作指针时,最常见的问题就是访问空指针和野指针。操作这两类指针产生的异常,均是因为使用该指针去访问了指向类对象的数据成员(把指针中存放的地址作为类对象首地址去访问),访问了不该访问的内存地址,引发了内存访问违例。对于空指针,在使用空指针访问了类对象的数据成员,就会访问很小的内存地址,小于64KB地址值的内存区域是禁止访问的。

       产生野指针,主要有两个场景

1)Release下没有对指针变量进行初始化,指针变量的值是个随机值,是分配内存时内存中残留的随机值,此时的指针就是野指针。
2)指针指向的内存被释放了,但指针没有置为NULL,此时的指针也是野指针。

通过野指针中的值去访问指向类的数据成员,也会触发访问不该访问的内存地址,触发内存访问违例,引发崩溃。 

3、C++程序中常见的异常内存值

       在讲述这个问题排查过程之前,需要先讲一下C++程序中常见的异常内存值,这了解这些异常内存值之后,可能就能知道是什么原因引发的,这样就给我们排查问题指明了方向。所以作为Windows C++开发人员,很有必要去了解这些常见的异常地址。

       C++程序中常见的异常内存值,如下所示(异常值不区分大小写,比如0xcdcdcdcd也可以写成0xCDCDCDCD):

* 0xcccccccc:Used by  Microsoft's C++ debugging runtime library and many DOS environments to mark uninitialized stack memory.CC resembles the opcode of the  INT 3 debug breakpoint interrupt on x86 processors.
* 0xcdcdcdcd:Used by  Microsoft's C/C++ debug malloc() function to mark uninitialized heap memory, usually returned from HeapAlloc().
* 0xfeeefeee:Used by  Microsoft's debug HeapFree() to mark freed heap memory. Some nearby internal bookkeeping values may have the high word set to FEEE as well.
* 0xdddddddd:Used by MicroQuill's SmartHeap and Microsoft's C/C++ debug free() function to mark freed heap memory.
* 0xabababab:Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory.
* 0xabadcafe:A startup to this value to initialize all free memory to catch errant pointers.
* 0xbaadf00d:Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory.
* 0xbadcab1e:Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger.
* 0xbeefcace:Used by Microsoft .NET as a magic number in resource files.

       这里我们主要关注0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd这四个异常内存值。这几个异常地址都是Debug下默认设置的,0xcccccccc用来填充未初始化的栈内存,0xcdcdcdcd用来填充未初始化的堆内存,0xfeeefeee用来填充已经释放的堆内存,0xdddddddd也是用来填充已经释放的堆内存。

0xfeeefeee和0xdddddddd都是用来填充已经释放的堆内存区域,但不太清楚这两个异常值的区别。我们经常在调试代码遇到0xfeeefeee,基本很少遇到过0xdddddddd,本案例还是第二次遇到0xdddddddd。

      我们需要对这些异常内存值有较强的敏感度,如果在调试代码中遇到这些异常值,要第一时间反应过来,通过这些异常内存值的含义,可以明确地提示我们当前访问的内存大概出了什么问题。这样我们排查时就有了一定的方向。

4、0xdddddddd内存访问违例问题分析与排查

       根据异常中断时的弹窗提示,当前访问了异常内存值0xdddddddd:

通过这个异常值的含义大概知道可能是访问了已经释放内存的野指针引发的。

       0xdddddddd异常值提示我们程序中访问了已经释放的内存区域,那我们需要去分析这块内存是何时释放的,以及为什么会出现访问已释放内存的问题。可以结合当前的函数调用堆栈,结合代码上下文的逻辑,大概就能分析出原因了。

4.1、初步分析

       根据Visual Studio中断的代码位置:

问题发生在COptionUI::Selected函数中,当前函数中的this指针值为0xddddddddd,即当前的COptionUI类对象的地址为0xddddddddd,通过该类对象地址去访问该类的数据成员m_bSelected产生了异常,数据成员m_bSelected的内存地址就是相对所在类的类对象首地址的偏移,是个内核态的内存地址,所以出现了内存访问违例,产生了崩溃。

       我们需要搞清楚当前出问题的COptionUI类对象位于那个具体的业务类中。沿着此时的函数调用堆栈,双击截图中的条目:

可以看到是CConfMeidaConfigDlg窗口类中的m_pBtnNotShow按钮控件指针的值为0xddddddddd,如下:

根据0xddddddddd的含义,是用来填充已经释放的堆内存的,所以基本可以确定m_pBtnNotShow所在的CConfMeidaConfigDlg类对象已经被delete了,即CConfMeidaConfigDlg类对象的内存被销毁了!


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

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

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

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

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

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

专栏2:  

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

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

专栏3: 

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

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

专栏4:   

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

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

专栏5: 

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

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


4.2、CConfMeidaConfigDlg窗口类对象是何时被销毁的?

       首先要搞清楚CConfMeidaConfigDlg类对象是何时被销毁的。很简单,我们直接在CConfMeidaConfigDlg类的析构函数中打个断点,复现一下问题,就知道了。

       在CConfMeidaConfigDlg类的析构函数中打了断点,然后重新启动调试,然后执行第一次操作,操作完成后命中了断点,如下所示:


查看此时的函数调用堆栈,是某个窗口消息触发CConfMeidaConfigDlg类对象销毁的。于是双击收发窗口消息的函数条目,进入函数:

是代码中给CConfMeidaConfigDlg窗口发送了WM_CLOSE,然后duilib框架将窗口类对象delete了。

4.3、为啥会访问到已经释放内存的CConfMeidaConfigDlg类对象?

       相关代码是其他同事写的,于是查看了代码的上下文逻辑,在软件执行当前的A操作时会去创建这个CConfMeidaConfigDlg窗口类:

但操作结束后并不会去销毁这个窗口,而是保存在成员变量中,下次再次执行当前的这个A操作时继续使用。

       但第一次执行A操作时,操作结束后CConfMeidaConfigDlg类对象就被销毁了,这个和原有的逻辑就不一致了。于是搜索WM_CLOSE消息,看看哪里给CConfMeidaConfigDlg窗口类发送了WM_CLOSE,然后找到了问题代码:

是这个地方发送了WM_CLOSE消息,后面还专门有个注释,于是查看svn的修改记录,原先是发送WM_UPDATE_CTRL_WINDOW消息,被一个同事改成了发送WM_CLOSE消息。这个同事有点不负责啊,没搞清楚代码的逻辑,就随意地修改了!

       上述代码在A操作动作结束后会被调用到,给CConfMeidaConfigDlg窗口类发送了WM_CLOSE消息,导致CConfMeidaConfigDlg窗口被销毁,CConfMeidaConfigDlg窗口类对象被析构(析构后会将原先分配给CConfMeidaConfigDlg对象的内存区域置为0xdddddddd),但存放CConfMeidaConfigDlg类对象地址的指针变量m_pConfMeidaConfigDlg并没有置空,指针变量中还是之前的类对象指针,这个指针就变成了野指针。

       再次执行A操作时,判断m_pConfMeidaConfigDlg指针变量不为空,就直接使用这个指针了,从而访问了野指针,从而出现访问0xdddddddd导致内存访问违例,引发崩溃的问题。

       解决办法很简单:

将上述代码中的WM_CLOSE改成之前的WM_UPDATE_CTRL_WINDOW消息即可

5、关于0xcdcdcdcd和0xfeeefeee异常值的排查案例

       关于常见异常内存值0xcdcdcdcd、0xfeeefeee和0xdddddddd的排查案例,可以参见我之前写的文章:
0xcdcdcdcd异常值引发C++程序崩溃问题的详细分析icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/128380751排查软件启动时访问了0xcdcdcdcd内存地址导致内存访问违例的崩溃icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125266735排查软件关闭时访问了0xfeeefeee内存地址导致内存访问违例的崩溃icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125267046访问0xdddddddd内存地址引发软件崩溃的问题排查icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/132631020

6、最后

       大家在调试代码要提高对0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd等常见异常内存值的敏感度,看到这些异常值就能大概地估计是什么原因导致的,这样我们就有了问题排查的方向。此外,在设置断点也要有一定的技巧,比如使用数据断点监测内存越界问题、人为添加if条件语句构造“条件”断点、在命中一个断点后再设置后续断点等等。

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

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

相关文章

(2)图像识别yolov5—识别图片视频等文件

目录 一、识别示例图片 二、识别视频 三、修改 detect.py 代码以输出物体坐标,更改识别方式 四、更改后的演示代码: 一、识别示例图片 在yolov5文件夹中,有两个示例图片,这里我们对示例图片进行识别。 打开命令行,进入到当前yolov5目录,通过运行下面的指令,然后对…

QTimer、QElapsedTimer、timeout()事件、singleShot事件

实现 QTimer 定时器 、timeout()事件、singleShot事件的使用 QElapsedTimer 计数器的使用 布局 设置第一个和第二个groupBox高度为固定 timerexample.cpp #include "timerexample.h" #include "ui_timerexample.h" #include "QTime" #include …

分享一个dnslog在线平台

DNSLog Platform 页面只有两个按钮,点击Get Subdomain可以随机生成一个dnslog 点击Refresh Record,刷新这个dnslog的记录。可以查看到这条dnslog的IP地址和创建时间。

QT6不自动生成pro文件

安装了QT的新版本结果他不自动生成pro文件了导致下次打开很复杂 记得在创建时选择qmake,因为新版默认cmake

大模型“诸神之战”,落地才是赛点

ChatGPT 诞生已经快一年,你还在与它对话吗? 有的人用来写报告、改代码,让它成为得力帮手;有的人却只是“调戏”个两三回,让它创作诗歌或故事,便不再“宠幸”。 根据网站分析工具 SimilarWeb 的数据&#…

delphi 如何使用TEdgeBrowser组件以及打包环境在其他主机上运行

不管开发环境还是第三方环境先安装运行时库:Microsoft Edge WebView2 | Microsoft Edge Developer 开发环境可以直接通过: delphi IDE安装 安装完毕后进入到指定路径,复制里面的WebView2Loader.dll到你要开发的程序根目录: 大致路…

未来工牌:蓝牙智联的彩色墨水屏工牌

在快节奏的现代职场中,传统的工牌已无法满足人们对于个性化和智能化的需求。为此,我们创新研发了一款4寸电子墨水屏工牌,它不仅仅是一个身份的象征,更是一个集蓝牙通信、智能显示、节能环保于一体的未来工具。 这款工牌拥有600*4…

电压模式R-2R DAC的工作原理和特性

本文将探讨电压模式R-2R DAC结构。 在本文中,我们将探索什么是R-2R DAC以及如何实现它们。 首先,我们将简要回顾一下开尔文分压器DAC。这种结构很简单,但它们需要大量的电阻和开关来实现高分辨率DAC。这个问题的一个解决方案是称为R-2R DAC…

用友YonSuite打通招银云直联,让企业收付款更便利

在当今数智化浪潮席卷全球的背景下,企业对于高效、便捷的管理系统需求日益增加。作为全球领先的企业云服务与软件提供商,用友始终站在技术前沿,致力于为成长型企业提供全方位的数智化解决方案。 用友网络与招商银行通过联通双方系统&#xf…

YOLOv8改进 | 卷积模块 | 用坐标卷积CoordConv替换Conv

💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录:《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40篇内容,内含各种Head检测头、损失函数Loss、B…

期货的心态

1.跌倒之后爬起过程中的收获 失败跌倒了,一定不要自暴自弃,而是要有跌倒不要紧,要相信爬起来的过程中都会有一定的收获,从交易错误中走出并升华,这就会一步步的使我们迈向更高层次的交易。 2.不要让今天的交易影响到明…

用Selenium自动化Web应用测试!

在开发和维护Web应用时,测试是确保应用正常运行的关键环节。手动测试不仅费时费力,而且容易出错。而通过使用Selenium,程序员可以轻松模拟用户交互、验证页面元素,从而自动化测试过程,提升测试效率和准确性。 解决的问…

第十五章 观察者模式

目录 1 观察者模式介绍 2 观察者模式原理 3 观察者模式实现 4 观察者模式应用实例 5 观察者模式总结 1 观察者模式介绍 观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者 一些产品的设计思路&#xff0c…

FREERTOS中,队列按键捕获

队列消息获取的按键任务优先级 < 队列消息释放的按键任务优先级 会出现错误&#xff0c;必须先按KEY1&#xff0c;才能按KEY0 解决方法&#xff1a;修改任务的优先级&#xff0c;队列消息获取的按键任务优先级 > 队列消息释放的按键任务优先级

Javaweb之web开发概述

一、Javaweb简介 用Java技术来解决相关web互联网领域的技术栈.使用JAVAEE技术体系开发企业级互联网项目. 项目规模和架构模式与JAVASE阶段有着很大的差别. 在互联网项目下,首先需要明白客户端和服务器的概念 客户端 :与用户进行交互&#xff0c;用于接收用户的输入(操作)、展示…

❤️‍❤️‍❤️‍FlyFlow 工作流:支持字典管理并支持表单引用

FlyFlow 介绍 官网地址&#xff1a;www.flyflow.cc 演示网址&#xff1a;pro.flyflow.cc FlyFlow 借鉴了钉钉与飞书的界面设计理念&#xff0c;致力于打造一款用户友好、快速上手的工作流程工具。相较于传统的基于 BPMN.js 的工作流引擎&#xff0c;我们提供的解决方案显著简…

20240619每日小程序-------朋友想开发微信小程序,那就搞一把demo

下载开发工具 hbuildX 微信开发者工具 随便搞个开源项目 会员小程序 下载后导入到hbuildX 安装依赖 npm i 安装hbuildX插件 工具—》插件安装 推荐安装&#xff1a; 微信小程序一键打包插件sass编译 启动 选择5.用微信开发者工具启动 报错不要怕 比如&#xff1a…

微信小程序生命周期分为3种:页面级别,应用级别,组件级别

应用级别&#xff1a; onLaunch&#xff0c;onShow&#xff0c;onHide 页面级别&#xff1a;onLoad&#xff0c;onShow&#xff0c;onReady&#xff0c;onHide&#xff0c;onUnload 组件级别&#xff1a;

硕思闪客精灵_2024最新版下载-闪客精灵软件下载_闪客精灵应用软件

​不同领域的应用证明了能够解析Flash动画片中的视频文件并以*.fla格式进行导出。人所共知的是支持预览和播放所选的Flash动画片或元素。我们都知道除了将静态文字恢复为文本外&#xff0c;硕思闪客精灵提供了将它转换为矢量图的功能。相信大家都认同闪客精灵专业版的优势&…

【3】Mcgs屏幕脚本程序

目录 1.脚本程序概述1.1 脚本程序简介1.2 脚本程序编辑环境 2.脚本程序语言要素2.1 变量和常量2.2 对象2.3 事件2.4 表达式2.5 联行符2.6 运算符2.7 系统函数 3. 基本语句3.1 赋值语句3.2 条件语句3.3 循环语句3.4 跳出语句3.5 退出语句3.6 注释语句3.7 声明语句3.6 命名规则 1…