制作网站的网站,云浮网站设计,开发公司交房前财务交付风险,知知网站推荐目录
1、问题描述
2、访问空指针或者野指针
3、常见的异常值
4、0xdddddddd内存访问违例问题分析与排查
5、关于0xcdcdcdcd和0xfeeefeee异常值的排查案例
6、最后 VC常用功能开发汇总#xff08;专栏文章列表#xff0c;欢迎订阅#xff0c;持续更新...#xff09;ht…目录
1、问题描述
2、访问空指针或者野指针
3、常见的异常值
4、0xdddddddd内存访问违例问题分析与排查
5、关于0xcdcdcdcd和0xfeeefeee异常值的排查案例
6、最后 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 在C软件中访问了有问题的指针变量可能会引发程序产生异常比如访问了空指针和野指针这也是操作指针错误最常见的原因。今天我们就来讲一个操作已经释放内存的野指针实例本例中的问题指针有些特殊释放内存后指针值变为0xdddddddd和以往常见的异常值0xfeeefeee有所不同。本文将详细讲述一下这个问题的完整分析过程以供大家借鉴或参考。
1、问题描述 某天在开发新功能使用Visual Studio在Debug下调试代码执行某一操作后程序就产生了异常Visual Studio中断了下来调到了发生异常的代码处显示代码处的指针m_pRoot值为0xdddddddd如下所示 此处是发生了崩溃。这行代码使用m_pRoot指针调用FindControl接口由于FindControl是虚函数调用时会触发虚函数调用时的二次寻址会去访问m_pRoot中存放的内存首地址0xddddddddd而对于32位程序这个地址属于内核态的内存地址用户态的代码是禁止访问的所以触发了内存访问违例产生了异常。 对于32程序系统会给程序进程分配4GB的虚拟内存其中0-2GB是用户态的内存2GB-4GB是内核态的内存用户态的代码不能访问内核态的内存内核态的代码也不能访问用户态的内存。强行访问就会触发内存访问违例引发程序崩溃。 2、访问空指针或者野指针 在操作指针时最常见的问题就是访问了空指针和野指针。操作这两类指针产生异常均是因为使用指针去访问了指向类的数据成员访问了不该访问的内存地址引发内存访问违例。对于空指针在使用空指针访问了类对象的数据成员就会访问很小的内存地址小于64KB地址值的内存区域是禁止访问的。 产生野指针主要有两个场景 1Release下没有对指针变量进行初始化指针变量的值是个随机值是分配内存时内存中残留的随机值此时的指针就是野指针。2指针指向的内存被释放了但指针没有置为NULL此时的指针也是野指针。 通过野指针中的值去访问指向类的数据成员可能会触发访问不该访问的内存地址触发内存访问违例引发崩溃。
3、常见的异常值 C程序中常见的异常值如下所示异常值不区分大小写比如0xcdcdcdcd也可以写成0xCDCDCDCD * 0xccccccccUsed by Microsofts 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.* 0xcdcdcdcdUsed by Microsofts C/C debug malloc() function to mark uninitialized heap memory, usually returned from HeapAlloc().* 0xfeeefeeeUsed by Microsofts debug HeapFree() to mark freed heap memory. Some nearby internal bookkeeping values may have the high word set to FEEE as well.* 0xddddddddUsed by MicroQuills SmartHeap and Microsofts C/C debug free() function to mark freed heap memory.* 0xababababUsed by Microsofts HeapAlloc() to mark no mans land guard bytes after allocated heap memory.* 0xabadcafeA startup to this value to initialize all free memory to catch errant pointers.* 0xbaadf00dUsed by Microsofts LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory.* 0xbadcab1eError Code returned to the Microsoft eVC debugger when connection is severed to the debugger.* 0xbeefcaceUsed 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内存访问违例问题分析与排查 根据异常中断时的弹窗提示当前的m_pRoot指针值为0xdddddddd通过这个异常值的含义大概知道可能是访问了已经释放内存的野指针引发的。 其实最开始看到0xdddddddd异常值并不知道其含义因为以前遇到访问已经释放内存的场景都是出现0xfeeefeee这个异常值从来没见过0xdddddddd这还是第一次遇到。后来到网上查了才知道0xdddddddd也是Debug下用来填充已经释放的内存区域的。 0xdddddddd异常值提示我们程序中访问了已经释放的内存区域那我们只要去分析这块内存是何时释放的结合当前访问的代码大概就知道原因了。但因为当前的代码逻辑比较复杂且相关模块不是我维护的直接去排查可能会比较费劲。 根据Visual Studio中断的代码位置 结合当时的函数的调用堆栈当时对应的类为CSmallVideoWndUI所以要排查这个必现的问题有个很好的办法在CSmallVideoWndUI的析构函数设置断点 一旦有delete CSmallVideoWndUI类对象时就会进入析构函数就会命中断点这样查看函数调用堆栈就知道是何处将CSmallVideoWndUI对象delete了。 但还有个问题很多代码都使用了该类代码中会频繁的new和delete CSmallVideoWndUI类对象所以直接在CSmallVideoWndUI析构函数中打断点可能会多次命中断点这样就不好确定哪次析构是和当前的问题相关的。所以还要再设置一个断点这个异常崩溃是执行鼠标双击操作引发的我们可以在双击消息的响应函数中先设置一个断点 当命中该断点后再到CSmallVideoWndUI类的析构函数中设置断点这样命中CSmallVideoWndUI析构函数断点时可能就和本问题有关了。 使用上述调试方法很快找到了问题代码解决了问题。
5、关于0xcdcdcdcd和0xfeeefeee异常值的排查案例 关于常见异常值0xcdcdcdcd和0xfeeefeee的排查案例可以参见我之前写的文章0xcdcdcdcd异常值引发C程序崩溃问题的详细分析https://blog.csdn.net/chenlycly/article/details/128380751排查软件启动时访问了0xcdcdcdcd内存地址导致内存访问违例的崩溃https://blog.csdn.net/chenlycly/article/details/125266735排查软件关闭时访问了0xfeeefeee内存地址导致内存访问违例的崩溃https://blog.csdn.net/chenlycly/article/details/125267046
6、最后 大家在调试代码要提高对0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd等常见异常值的敏感度看到这些异常值就能大概地估计是什么原因导致的这样我们就有了问题排查的方向。此外在设置断点也要有一定的技巧比如使用数据断点监测内存越界问题、人为添加if条件语句构造“条件”断点、在命中一个断点后再设置后续断点等等。