学校网站建设板块分析,钢材网站模板,上海短视频推广,做网站云服务器2m宽带够用吗目录
1、概述
2、打开dump文件#xff0c;查看发生异常的异常类型码
3、查看发生异常的那条汇编指令
3.1、汇编代码能最直接、最本真的反映出崩溃的原因
3.2、汇编指令中访问64KB小地址内存区#xff0c;可能是访问了空指针
3.3、汇编指令中访问了很大的内核态的内存地…目录
1、概述
2、打开dump文件查看发生异常的异常类型码
3、查看发生异常的那条汇编指令
3.1、汇编代码能最直接、最本真的反映出崩溃的原因
3.2、汇编指令中访问64KB小地址内存区可能是访问了空指针
3.3、汇编指令中访问了很大的内核态的内存地址
3.4、汇编指令中访问了一个正常的内存地址可能是野指针
4、查看发生崩溃时的函数调用堆栈
5、可以尝试在Windbg中查看相关变量的值可能是排查问题的关键线索
6、有时可能需要尝试找到复现问题的方法和步骤确定代码的排查范围和方向
7、有时可能需要查看二进制文件的汇编代码上下文去辅助分析问题
8、最后 C软件异常排查从入门到精通系列教程专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/125529931C/C实战专栏专栏文章已更新460多篇持续更新中...https://blog.csdn.net/chenlycly/article/details/140824370C 软件开发从入门到精通专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12695902.htmlVC常用功能开发汇总专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/124272585C软件分析工具从入门到精通案例集锦专栏文章持续更新中...https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_2276111.html 当程序发生异常崩溃时程序中安装的异常捕获模块感知到了异常自动生成了dump文件事后用Windbg静态分析dump文件去排查异常这是分析程序异常的常用方法。但技术群中很多朋友反映不知道该如何分析表示无从下手普遍缺乏分析问题的思路与方法。所以今天在这里总结一下使用Windbg分析dump文件去排查C软件异常的一般步骤与方法供大家借鉴或参考。
1、概述 使用Windbg静态分析dump文件是排查C软件异常与崩溃的常见手段与方法。使用Windbg分析dump文件的思路和流程大概是这样子的 1用Windbg打开dump文件后先看一下发生的异常类型可能能找到直接的线索。 2紧接着查看发生异常的那条汇编指令汇编指令中可能访问了不该访问的内存可以初步地估计出引发该内存访问的可能原因作为排查问题的方向和线索。 3接下来就是查看发生异常的线程的函数调用堆栈对照着C源码去分析。 4必要时可能需要在Windbg中查看函数中相关变量的值这些变量的值可能是关键线索。 5此外在分析不出问题时可能要使用IDA反汇编工具查看二进制文件的汇编代码上下文去辅助分析。 6有时可能需要尝试找到复现问题的方法和步骤确定代码的排查范围和方向。 2、打开dump文件查看发生异常的异常类型码 取来dump文件用Windbg打开就能看到程序中发生的异常类型码如下所示 通过这个异常类型码可以初步判断出异常的种类比如Access violation内存访问违例、Integer divided by zero除0异常、Stack overflow线程栈溢出、Stack buffer overrun栈内存越界等通过这个异常类型码可能就能找到最直接的线索。 比如Integer divided by zero除0异常异常就是代码中出现除数为0的情况查看异常发生时的函数调用堆栈就能快速定位。 再比如Stack overflow线程栈溢出异常就是发生异常的线程的函数调用堆栈中函数占用的栈空间达到了系统给线程分配的栈内存的上限直接去查看异常发生时的函数调用堆栈就能快速定位问题。之前在文章中总结过引发线程栈溢出异常的常见原因 1函数递归调用的深度过深 因为一直在递归调用在到达最底下的那层调用之前递归函数一直没返回栈空间一直没有释放导致当前线程占用的栈空间越来越多达到上限。2消息上触发函数的死循环调用 消息触发的函数死循环调用因为死循环调用了函数的栈空间一直没释放导致当前线程占用的栈空间越来越多。这个问题我们在实际项目中遇到过两次。3定义了一个占用内存很大的局部变量 比如定义了一个很庞大的结构体在一个函数中用该结构体定义了一个局部变量假设该结构体接近或者大于1MB则会直接导致线程栈溢出。4函数中使用switch...case语句包含了大量的case分支 每个case分支中都定义了局部变量导致当前函数占用了大量的栈空间。case分支中的局部变量的生命周期是在case分支中的即代码运行到对应的case分支中时该分支中的局部变量才有“生命”但其实这个局部变量的栈空间已经在函数入口处分配好栈空间了并不是代码执行到case子句中才分配栈空间的。这点可以通过编写测试代码查看函数入口处给当前函数分配栈空间的汇编代码就能看出来了可以先顶一个变量查看汇编代码看看分配了多少栈空间然后再增加一个变量看看分配的栈空间是否变大。5多个if-else分支每个分支中都有定义局部变量 引发问题的原因与多个case语句的场景是一样的此处就不再赘述了。本问题案例的场景就是与if-else分支有关系的。 对于Access violation内存访问违例的异常就是程序中访问了不该访问的内存原因比较多比如访问空指针或野指针、访问内核态内存地址、访问已经释放的内存等都会引发内存访问违例内存访问违例就没有明确的问题指向性了就要查看函数调用堆栈与源码进行详细分析了。
3、查看发生异常的那条汇编指令 打开dump文件输入.ecxr命令切换到发生异常的线程上下文可以查看到发生异常崩溃的那条汇编指令以及各个寄存器的值如下所示 查看发生异常的那条汇编指令可能能找到初步的线索。比如汇编指令中访问了一个很小的内存地址可能是访问了空指针导致的。再比如汇编指令中访问了一个很大的内核态的内存地址可能是访问了未初始化的指针变量导致的用户态的代码是不允许访问内核态内存地址会触发内存访问违例。围绕着这些初步的估计线索对照着函数调用堆栈去查看C源码这样排查的方向可能更明确、更有针对性效率更高。
3.1、汇编代码能最直接、最本真的反映出崩溃的原因 程序运行时执行的是二进制文件中的汇编代码或者称为二进制机器码二进制机器码和汇编代码是等价的程序最终崩溃在某条汇编指令上汇编指令能直观的反映出崩溃的原因。 比如我们都知道访问空指针可能会引发崩溃但为啥会崩溃呢其实是汇编指令中访问了很小的内存地址而系统禁止访问这个小地址内存区域一旦访问就会触发内存访问违例引发崩溃。 再比如访问野指针对应的汇编指令中可能访问了之前已经释放的内存或者一个随机的未知内存一定会触发内存访问违例吗答案是不一定系统允许你访问你就能访问系统不允许你访问则会触发内存访问违例。
3.2、汇编指令中访问64KB小地址内存区可能是访问了空指针 在Windows系统中0到64KB以内的小内存地址区域是禁止访问的该区域被称为空指针内存区专门用来协助程序员去排查访问空指针问题的。如果程序访问这个范围内的内存则会触发内存访问违例系统会强行将进程终止掉。 导致代码访问小地址内存区域可能有以下几个原因 1访问了空指针 程序中访问了空指针通过空指针去访问类的成员变量类的成员变量的地址就是相对所在类对象首地址的偏移如果类对象地址是空指针则访问成员变量的地址就很小这样就产生了访问小内存地址的场景。2访问了未初始化的指针 还可能是访问了一个未初始化的指针引起的指针未初始化则指针值是给指针变量分配的内存中残留的随机值这个随机值可能很小所以也会触发访问小地址内存区域。3程序中发生内存越界指针变量的值被篡改了 程序中发生了内存越界指针变量的值被篡改了可能被篡改成一个很小的值该值对应着一个很小的内存地址。 在这里给大家重点推荐一下我的几个热门畅销专栏欢迎订阅博客主页还有其他专栏可以去查看
专栏1该精品技术专栏的订阅量已达到520多个专栏中包含大量项目实战分析案例有很强的实战参考价值广受好评专栏文章持续更新中预计更新到200篇以上欢迎订阅
C软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931 本专栏根据多年C软件异常排查的项目实践系统地总结了引发C软件异常的常见原因以及排查C软件异常的常用思路与方法详细讲述了C软件的调试方法与手段以图文并茂的方式给出具体的项目问题实战分析实例很有实战参考价值带领大家逐步掌握C软件调试与异常排查的相关技术适合基础进阶和想做技术提升的相关C开发人员 考察一个开发人员的水平一是看其编码及设计能力二是要看其软件调试能力所以软件调试能力排查软件异常的能力很重要必须重视起来能解决一般人解决不了的问题既能提升个人能力及价值也能体现对团队及公司的贡献 专栏中的文章都是通过项目实战总结出来的包含大量项目问题实战分析案例有很强的实战参考价值专栏文章还在持续更新中预计文章篇数能更新到200篇以上 专栏2本专栏涵盖了C多方面的内容是当前重点打造的专栏订阅量已达160多个专栏文章已经更新到400多篇持续更新中...
C/C实战进阶专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_11931267.html 以多年的开发实战为基础总结并讲解一些的C/C基础与项目实战进阶内容以图文并茂的方式对相关知识点进行详细地展开与阐述专栏涉及了C/C领域多个方面的内容包括C基础及编程要点模版泛型编程、STL容器及算法函数的使用等、数据结构与算法、C11及以上新特性不仅看开源代码会用到日常编码中也会用到部分新特性面试时也会涉及到、常用C开源库的介绍与使用、代码分享调用系统API、使用开源库、常用编程技术动态库、多线程、多进程、数据库及网络编程等、软件UI编程Win32/duilib/QT/MFC、C软件调试技术排查软件异常的手段与方法、分析C软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等、设计模式、网络基础知识与网络问题分析进阶内容等。 专栏3
C常用软件分析工具从入门到精通案例集锦汇总专栏文章持续更新中...https://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常用功能开发汇总专栏文章持续更新中...https://blog.csdn.net/chenlycly/article/details/124272585 将10多年C开发实践中常用的功能以高质量的代码展现出来。这些常用的高质量规范代码可以直接拿到项目中使用能有效地解决软件开发过程中遇到的问题。 专栏5
C 软件开发从入门到精通专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12695902.html 根据多年C软件开发实践详细地总结了C/C软件开发相关技术实现细节分享了大量的实战案例很有实战参考价值。 3.3、汇编指令中访问了很大的内核态的内存地址 对于32位程序系统会给进程分配4GB的虚拟内存一般情况下用户态和内核态会各占一半即各占2GB我们编写的代码基本都是运行在用户态的用户态的代码时不能访问内核态内存地址的内核态地址是供系统内核模块使用的。 如果汇编指令中访问了一个很大的内存地址超过用户态的地址范围0-2GB内存地址大于0x8000000即访问了一个内核态的内存地址则会触发内存违例因为用户态的代码是禁止访问内核态内存地址的。 为什么代码中会访问内核态内存地址呢可能有两个原因 1访问了一个未初始化的指针 Release下指针未初始化则指针值是给指针变量分配内存时内存中残留的随机值这个随机值可能很大可能是内存态的内存地址。2程序中发生内存越界指针变量的值被篡改了 程序中发生了内存越界指针变量的值被篡改了可能被篡改成一个很大的值该值对应着内核态的内存地址。 3.4、汇编指令中访问了一个正常的内存地址可能是野指针 当前发生崩溃的这条汇编指令中访问了一个正常的内存地址既不是很小的内存地址也不是很大的内核态内存地址。很可能是访问的野指针野指针主要包含以下两种情况 1该野指针可能是未初始化的指针变量。指针值是给指针变量分配内存时内存中残留的随机值。 2可能是指针指向的内存已经被释放了指针的值就是其指向的内存地址而指针变量没有置为NULL代码中又访问了该指针变量。 之前在项目中就遇到这个场景发生崩溃的汇编指令中访问了一个正常的内存地址产生了内存访问违例查看崩溃的函数调用堆栈一直找不到引发问题的原因。后来又回到这个汇编指令大概地思考了一下从这个访问的内存地址入手既然访问的是一个正常的内存地址内存地址不小也不大在正常范围有没有可能该内存地址空间被释放了呢代码中在释放内存时没有将指针变量置为NULL所以出现代码中访问已释放内存的野指针的场景。后来围绕这个可能的线索根据函数调用堆栈去查看C源码然后就快速地定位了问题。相关的问题案例之前已经写成了文章可以查看
根据发生异常的汇编指令以及函数调用堆栈估计出问题的原因确定排查方向快速定位问题https://blog.csdn.net/chenlycly/article/details/141869579
4、查看发生崩溃时的函数调用堆栈 查看异常崩溃时的函数调用堆栈是我们分析问题的最重要的线索。根据函数调用堆栈去查看C源码引发问题的点可能就在当前的调用堆栈中的函数中当然也可能在其他处的代码中代码崩溃有时具有延后性执行到引发问题的代码点时不会立即崩溃在执行到后续代码时发生崩溃。 用Windbg打开dump文件输入.ecxr命令切换到发生异常的那个线程输入kn命令查看发生异常时的函数调用堆栈 要查看到详细的函数调用堆栈信息比如具体的函数名以及代码的行号需要根据模块的时间戳找到对应的pdb文件然后将pdb的路径设置到Windbg中然后重新输入.ecxr命令和kn命令就可以查看到详细的函数调用堆栈了。 这里需要注意一下函数调用堆栈可能会显示代码崩溃在Windows系统库或者开源库比如duilib模块中一般问题都不在系统库或开源库中问题应该出在上层的模块中要到上层模块中找问题很多时候要从内存的角度去分析。比如上层操作的类对象地址有问题可能对象内存已经释放了但上层还在使用再次访问就会出现内存访问违例导致程序崩溃。
5、可以尝试在Windbg中查看相关变量的值可能是排查问题的关键线索 我们看到了发生异常时的函数调用堆栈然后根据堆栈去详细查看源码有时分析问题原因可能需要查看相关变量的值可以直接尝试在Windbg中查看变量的值可能是关键的线索。在Windbg中查看变量值的一个示例截图如下所示 之前写过相关的实战问题分析案例可以查看我的文章通过查看Windbg中变量值去定位C软件异常问题https://blog.csdn.net/chenlycly/article/details/125731044通过查看Windbg中变量值去定位C软件异常的又一典型案例分享https://blog.csdn.net/chenlycly/article/details/125793532
6、有时可能需要尝试找到复现问题的方法和步骤确定代码的排查范围和方向 因为执行了引发问题的代码其导致后续的崩溃会有延后性通过崩溃时的代码没法找到引发问题的代码可能需要尝试找到复现问题的方法和步骤确定代码的排查范围和方向。 复现问题找到复现问题的方法也是排查问题的一种有效的辅助手段与方法。 有时我们需要让测试人员去复现问题找到复现问题的方法与步骤通过复现的步骤确定问题与哪些操作有关这样就能大概确定问题与哪块代码有关这样就确定了代码的排查范围和方向然后在查阅对应代码的过程中结合用户执行的操作复现问题的步骤查找代码中存在的逻辑控制错误或业务异常。 对于软件UI异常或者业务异常我们可能会尝试去找问题的复现办法或者是我们在使用一些方法和手段去排查但很难定位问题时也希望测试人员去尝试复现问题。 再比如有些问题是在客户环境中出现的在公司测试环境中没出现过问题很难排查定位我们可能需要尝试在公司环境中复现如果能复现在公司环境中排查起来也比较方便。
7、有时可能需要查看二进制文件的汇编代码上下文去辅助分析问题 有时我们查看C源代码很难搞清楚问题到底出在那句代码上或者无法排查出问题时我们可能就需要查看汇编代码上下文去分析了。软件最终是崩溃在某一条汇编指令上通过查看汇编代码才能最直观的看出为什么会发生异常崩溃。 在Windows平台下我们主要使用IDA Pro反汇编工具打开二进制文件去查看二进制文件中的汇编代码。我们一般对汇编代码不是很精通我们需要将C源代码和汇编代码对照看找到汇编代码与C源码的对应关系同时依靠汇编代码中的注释才能大概地看懂汇编代码的上下文。 有一点需要注意release下编译器在编译时会对代码进行优化这样可能会导致汇编代码有时较难和C源代码完全对应起来比如有变量被优化掉、有函数调用被优化掉。 要阅读汇编代码上下文需要掌握一些基础的汇编知识这些基础汇编知识可以查看我之前写的文章
分析C软件异常需要掌握的汇编知识汇总https://blog.csdn.net/chenlycly/article/details/124758670 至于如何使用IDA Pro反汇编工具以及实战问题分析案例可以参看我的文章
反汇编工具IDA使用详解使用IDA查看二进制文件的汇编代码以及使用IDA分析崩溃问题实例分享https://blog.csdn.net/chenlycly/article/details/120635120使用IDA查看汇编代码结合安卓系统生成的Tombstone文件分析安卓app程序崩溃问题https://blog.csdn.net/chenlycly/article/details/132283582 此外C开发人员要了解汇编了解汇编后有诸多的好处。不仅可以辅助排查C软件异常问题还可以理解很多高级语言不好理解的代码执行细节从汇编代码的角度可以看到代码的完整执行细节特别是多线程编程中的问题。关于为什么要学习汇编以及学习汇编有哪些好处可以查看我的文章C/C程序员为什么要了解汇编了解汇编有哪些好处如何学习汇编https://blog.csdn.net/chenlycly/article/details/142795872
8、最后 本文详细讲述了使用Windbg分析dump文件去排查程序异常的一般方法与思路并给出了一些实战问题分析实例以文章链接的方式提供有一定的实战参考价值希望能帮到大家。本文讲到了Windbg分析dump文件的要点至于使用Windbg分析dump文件的详细操作步骤及相关问题分析实例可以参考我的文章
使用Windbg分析dump文件的一般步骤详解https://blog.csdn.net/chenlycly/article/details/135484682