




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、定位Crash错误 1. 在开发环境下定位Crash错误1.1 普通的crash1.2 较难定位的crash1.3 注意vc的输出日志2. 定位发布在外的版本的Crash错误3. 小技巧3.1 根据程序地址找到代码位置3.2 根据消息值查看对应的windows消息3.3 查看GetLastError返回值3.4 在代码中暂停程序4. 编程小警示4.1 慎用IsBadPtr系列函数4.2 慎用catch(.)5. 附录5.1 为什么程序crash时调用堆栈是乱的5.2 使用Debugging tools for windows查看.dmp文件(错误报告)-1. 在开发环境下定位Crash错误1.
2、1 普通的crash先来看看最普通的crash参见图1(c01.png)当你在debug模式下运行上面的程序就会弹出上面的框。vc就帮你定位到了错误的位置。是个对零指针的操作。非常简单,不是吗。1.2 较难定位的crash较难定位的crash往往是由于内存错误(参见5.1 为什么程序crash时调用堆栈是乱的)。例如以下代码:代码char *p = new char16;p10 = 0xfd;delete p;printf(p);以上代码有两处错误,一是第2行的内存写越界,二是第4行使用被删除的指针。但以上代码在vc的release和debug下都不会报错。这使得这类错误很难定位。检测这一类问
3、题可以使用BoundsChecker工具的FinalCheck模式(使用方法见此文章)用BoundsChecker检测后可得到两个错误:Write overrun(写越界) 和 Dangling pointer(使用被删除的指针)而且都精确定位到了出错的位置。是个不错的工具。参见图2(c02.png)参见图3(c03.png)1.3 注意vc的输出日志由于一些目前未知的原因(有可能是程序的错误太严重或是BoundsChecker本身的bug),BoundsChekcer有时不能正常工作。这里vc的输出日志有时能提供一些有用的信息。在难找的crash中,有很大一部分是引用了非法的指针。有时在vc
4、的输出日志里可以看到类似于这样的信息“emule.exe 中的 0x004277b7 处最可能的异常: 0xC0000005: 读取位置 0xfeeeff62 时发生访问冲突 。”在缺少BoundsChecker的支持时,这是一条很重要的信息。意思是说在“程序地址0x004277b7处”对“值为0xfeeeff62的指针”进行操作。(怎么通过“程序地址0x004277b7”找到对应的代码行可参照 3.1,)这条信息的重要性在于,这个操作只会触发一个警告,而不会导致crash,当crash真正发生时,很有可能不会在0x004277b7附近, 甚至调用堆栈都已经被写乱,让你无从下手。(参见5.1
5、为什么程序crash时调用堆栈是乱的)2. 定位发布在外的版本的Crash错误发布在外的软件crash了,往往不好调试,所以目前很多软件都有“发送错误报告”这一功能。实现这一功能一般分以下几步:a. 使用SetUnhandledExceptionFilter函数使用SetUnhandledExceptionFilter设置最高一级的异常处理函数,当程序出现任何未处理的异常,都会触发你设置的函数里。具体使用可参照msdn和emule源码。b. 使用MiniDumpWriteDump函数在你的异常处理函数里,使用MiniDumpWriteDump把错误信息存成特定格式的文件。具体使用可参照msdn
6、和emule源码。c. 发送错误报告选用一种形式把第二步产生的错误报告(.dmp)文件发送给你指定的地方。d. 查看错误报告这里介绍用vc查看错误报告的方法,还可以用windows debug tools这个工具看,方法见5.2 使用windows debug tools查看.dmp文件(错误报告)查看错误报告需要有三样东西:对应release版的代码,当时编译release版所产生的.exe和.pdb文件。(这两个文件都在编译的输出目录里。)所以当程序发布时,要保留下这两个文件。把.dmp(错误报告文件), .pdb, .exe. 代码,在同一目录下,用vc打开.dmp 文件。按F5运行,程
7、序即到达crash时的状态,可以对其进行相应的分析。一点补充:当没有“发送错误报告”的功能,或是此功能失效,以致弹出了windows的“发送错误报告”的对话框。这时其实也是有错误报告的,一般在C:Documents and Settings用户名Local SettingsTemp里的一个.dmp文件(一般只有一个.dmp)3. 小技巧3.1 根据程序地址找到代码位置可按如下步骤:a. 使程序处于停止状态。(比如程序运行时,在vc里按Ctrl+Alt+Break,或设断点使程序停下)b. 切换到汇编状态。(Ctrl+F11)c. 在地址栏输入程序地址,回车。 d. 可按Ctrl+F11切回代码
8、模式。3.2 根据消息值查看对应的windows消息在vc的监视窗口里输入“消息值,wm”即可看到对应的消息。3.3 查看GetLastError返回值在vc的监视窗口里输入“err,hr”,即可看到LastError及其解释。3.4 在代码中暂停程序在debug版中可以在代码中加上“AfxDebugBreak();”以暂停程序。release版可使用 “_asm int 3;”4. 编程小警示4.1 慎用IsBadPtr系列函数当使用IsBadReadPtr, IsBadWritePtr, IsBadCodePtr一系列函数时要注意,这一类函数可能并不能达到你所想要的意图 。比如下面的代码,
9、两个返回都是false。代码char *p = new char10;bool b;b = IsBadReadPtr(p+10, 1);delete p;char *q = new char10;b = IsBadReadPtr(p, 1);所以切忌在程序中以IsBadPtr函数来判断是否可以对这个指针进行操作。这些函数只能在调试中使用,或是你确切的知道这些函数的返回值表示的是什么意义的时候。4.2 慎用catch(.)为了防止程序crash或是解决一个不明白的crash时,大家很容易想到一个 trycatch(.)来解决问题。的确大部分时间这样不会出问题了,但这个try-catch很有可能隐
10、藏掉在try里面的错误,而当由此错误引起其他错误时,就很难追踪到这个问题了。所以建议尽量少用catch(.),如果知道某一块代码会抛出异常,应该用确切的写法。比如catch(CFileException *e), catch(int e)等等。5. 附录5.1 为什么程序crash时调用堆栈是乱的当内存被写乱时程序很有可能出现很难定位的crash,比如调用堆栈是乱的,或走到不存在的代码里。这里举一例代码class CApublic:CA()CA()virtual f();void show()printf("shown");int main()/ 对像被创建
11、删除CA *p = new CA;delete p;/ 一些正常的操作int *q = new int;int codeAddress = (int)show;*q = (int)&codeAddress;/ 调用被删除的对像,程序有可能执行到任何地方。p->f();上面代码的结果会走到show()里显示出show(这跟编译环境有关,vc2003下测试结果是这样)。如果你了解c+的vtable机制就明白这是怎么回事。如果不明白也没关系,我下面说个大概。首先CA对象被创建又被删除。如果此时调用p->f()多半会crash。第二块代码可视为一些正常的操作
12、,new了一个q,然后对它进行了一些赋值。如果你不明白vtable机制,那你只要知道,最后一行的 “p->f();”会执行变量q所指向的变量所指向的变量所标示的地址。(这里没打错字,是两个“所指向的变量”)这里我“心地善良”的给这个值赋上了一个合法的函数地址show。但实际程序中q所指向的变量有可能是任意值,它再指向的变量就更是任意值了。那程序就不知道跑哪里去了。如果这个值过于离谱,那算你运气好,程序会立即crash,而你就知道错误位置在哪了。但讨人厌的是,它有可能是一个合法地址,那程序就继续走下去,但迟早会crash,并且调用堆栈面目全非(原因牵涉到“调 用堆栈的推导”的问题这里就不多说了),到时就根本无从知道原来是调用了被删除的p对象而导致的。5.2 使用Debugging tools for windows查看.dmp文件(错误报告)a. 准备好程序对应的代码
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业抵押贷款合同样本参考
- 项目经理劳动合同范文
- 足球俱乐部球员转会合同协议范本新
- 移动通信设备区域分销合同范本
- 道路硬化改造提升施工合同书
- 股权转让合同典范解析
- 跨区域旅游合作:组团社与地接社合同范本
- 塑料挤出机节能改造技术考核试卷
- 市场营销与电子支付方式考核试卷
- 厨房用品消费者满意度调查考核试卷
- 醛固酮增多症与原发性醛固酮增多症概述
- 安全生产治本攻坚三年行动实施方案(2024-2026年) - 副本
- 山东省淄博市2023-2024学年高一下学期期末教学质量检测数学试题
- 2025届新高考生物精准复习+提高农作物产量
- TD/T 1037-2013 土地整治重大项目可行性研究报告编制规程(正式版)
- 2024年时政试题库(夺分金卷)
- 2024年江苏农林职业技术学院单招职业适应性测试题库及答案1套
- 工程项目移交方案
- 高级英语-第一册-课后习题答案
- 《带电作业用绝缘工具试验导则》
- 2024年时事政治热点题库200道附完整答案【必刷】
评论
0/150
提交评论