博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
调试Release发布版程序的Crash错误(一)
阅读量:2181 次
发布时间:2019-05-01

本文共 1374 字,大约阅读时间需要 4 分钟。

转自

 

非常感谢作者提供了一个系统的解决方案

 

在Windows平台下用C++开发应用程序,最不想见到的情况恐怕就是程序崩溃,而要想解决引起问题的bug,最困难的应该就是调试release版本了。因为release版本来就少了很多调试信息,更何况一般都是发布出去由用户使用,crash的现场很难保留和重现。本文将给出几个解决方案,完成对release版应用程序crash错误的调试。(本文只讨论Windows平台MSVC环境下的调试,对于其他平台和开发环境没有关注,请大家自己借鉴和尝试。)

 

    方案一:崩溃地址 + MAP文件

    这种方案只能对VC7以前的版本开发的程序使用。 

    1、崩溃地址

     所谓崩溃地址就是引起程序崩溃的内存地址,在WinXP下应用程序crash的对话框如下图:

     

     

    上面第2张图中画红线的值为crash的代码偏移地址,第3张图为即crash绝对地址;一般引起crash的原因多为内存操作错误,我们用这两个地址和MAP文件就能定位出错的代码行。

    2MAP文件

    MAP文件是记录应用程序信息的文件(文本文件),里面大概包含了程序的全局符号、源码模块名、源码文件和行号等信息,而这些信息能够帮助我们定位出错的代码行。

    怎样生成MAP文件呢?以VC6为例,在 Project Settings -> C/C++ -> Debug info中,选择 Line Numbers Only ;在 Project Settings -> Link 中,选择 Generate mapfile项,并在Project Options 里面输入/MAPINFO:LINES 和 /MAPINFO:EXPORTS,重新编译程序就会生成.map文件。

    以上设置对应的编译链接选项分别分:

    /Zi — 表示生成pdb调试信息;

    /MAP[:filename] — 表示生成map文件名;

    /MAPINFO:EXPORTS  — 表示生成的map文件中加入exported functions(生成DLL文件时);

    /MAPINFO:LINES  — 表示生成的map文件中加入代码行信息。

    由于/MAPINFO:LINES选项在VC8以后的版本中不再支持,因此通过MAP文件中的信息和crash地址定位出错代码行就比较困难了,所以这种方案只能在VC7及以前的版本中使用。

    一个MAP文件片段示例如下: 

    

    

    图中Rva+Base列的地址为该行函数对应的函数绝对地址,Address列中冒号后面的地址为函数相对偏移地址。   

    3、定位crash代码

    有了上面的介绍,定位crash代码就很简单了。用下面的公式来进行定位:

    崩溃行偏移 = 崩溃地址 - 崩溃函数绝对地址 + 函数相对偏移

    我们首先根据崩溃地址(绝对地址),按照找到第2张图中Rva+Base列的地址找到发生崩溃的函数(即崩溃地址大于该函数行的Rva+Base地址且小于下个函数的地址),然后找到该行对应的函数相对偏移地址,带入公式中,就得到了崩溃行偏移,该值表示崩溃行的代码相对于代码所在函数的偏移量。用该值去与第3张图中对应函数冒号后面的偏移量去比较,最接近的值前面的那个十进制数即为代码所在函数中的行号。

    ok,到此我们已经成功找到了崩溃的代码行,只不过这种方法还是比较费力,并且限制比较多,我们看看下面的方案。

转载地址:http://hhikb.baihongyu.com/

你可能感兴趣的文章
Java网络编程与NIO详解8:浅析mmap和Direct Buffer
查看>>
Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型
查看>>
Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)
查看>>
深入理解JVM虚拟机1:JVM内存的结构与消失的永久代
查看>>
深入理解JVM虚拟机3:垃圾回收器详解
查看>>
深入理解JVM虚拟机4:Java class介绍与解析实践
查看>>
深入理解JVM虚拟机5:虚拟机字节码执行引擎
查看>>
深入理解JVM虚拟机6:深入理解JVM类加载机制
查看>>
深入了解JVM虚拟机8:Java的编译期优化与运行期优化
查看>>
深入理解JVM虚拟机9:JVM监控工具与诊断实践
查看>>
深入理解JVM虚拟机10:JVM常用参数以及调优实践
查看>>
深入理解JVM虚拟机11:Java内存异常原理与实践
查看>>
深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战
查看>>
深入理解JVM虚拟机13:再谈四种引用及GC实践
查看>>
Spring源码剖析1:Spring概述
查看>>
Spring源码剖析2:初探Spring IOC核心流程
查看>>
Spring源码剖析3:Spring IOC容器的加载过程
查看>>
Spring源码剖析4:懒加载的单例Bean获取过程分析
查看>>
Spring源码剖析5:JDK和cglib动态代理原理详解
查看>>
Spring源码剖析6:Spring AOP概述
查看>>