问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
你好,欢迎来到懂视!登录注册
当前位置: 首页 - 正文

如何定位导致Crash的代码位置

发布网友 发布时间:2022-04-30 02:02

我来回答

2个回答

懂视网 时间:2022-04-30 06:23

博客搬到了fresky.github.io - Dawei XU,请各位看官挪步。最新的一篇是:如何用Windbg找到被catch住的C++的异常。

如何用Windbg找到被catch住的C++的异常

标签:

热心网友 时间:2022-04-30 03:31

1. 在开发环境下定位Crash错误
  1.1 普通的crash
    先来看看最普通的crash
    参见图1(c01.png)
    当你在debug模式下运行上面的程序就会弹出上面的框。vc就帮你定位到了错误的位置。是个对零指针的操作。非常简单,不是吗。

  1.2 较难定位的crash
    较难定位的crash往往是由于内存错误(参见5.1 为什么程序crash时调用堆栈是乱的)。例如以下代码:

代码

    char *p = new char[16];
    p[10] = 0xfd;
    delete[] p;
    printf(p);

    以上代码有两处错误,一是第2行的内存写越界,二是第4行使用被删除的指针。
    但以上代码在vc的release和debug下都不会报错。这使得这类错误很难定位。
    检测这一类问题可以使用BoundsChecker工具的FinalCheck模式(BoundsChecker)

    用BoundsChecker检测后可得到两个错误:Write overrun(写越界) 和 Dangling pointer(使用被删除的指针)而且都精确定位到了出错的位置。是个不错的工具。
    参见图2(c02.png)
    参见图3(c03.png)

  1.3 注意vc的输出日志
    由于一些目前未知的原因(有可能是程序的错误太严重或是BoundsChecker本身的bug),BoundsChekcer有时不能正常工作。
    这里vc的输出日志有时能提供一些有用的信息。
    在难找的crash中,有很大一部分是引用了非法的指针。

    有时在vc的输出日志里可以看到类似于这样的信息
    “emule.exe 中的 0x004277b7 处最可能的异常: 0xC0000005: 读取位置 0xfeeeff62 时发生访问冲突 。”
    在缺少BoundsChecker的支持时,这是一条很重要的信息。意思是说在“程序地址0x004277b7处”对“值为0xfeeeff62的指针”进行操作。
    (怎么通过“程序地址0x004277b7”找到对应的代码行可参照 3.1,)
    这条信息的重要性在于,这个操作只会触发一个警告,而不会导致crash,当crash真正发生时,很有可能不会在0x004277b7附近,
    甚至调用堆栈都已经被写乱,让你无从下手。(参见5.1 为什么程序crash时调用堆栈是乱的)

2. 定位发布在外的版本的Crash错误
  发布在外的软件crash了,往往不好调试,所以目前很多软件都有“发送错误报告”这一功能。
  实现这一功能一般分以下几步:

  a. 使用SetUnhandledExceptionFilter函数
    使用SetUnhandledExceptionFilter设置最高一级的异常处理函数,当程序出现任何未处理的异常,都会触发你设置的函数里。具体使用可参照msdn和emule源码。
  b. 使用MiniDumpWriteDump函数
    在你的异常处理函数里,使用MiniDumpWriteDump把错误信息存成特定格式的文件。具体使用可参照msdn和emule源码。
  c. 发送错误报告
    选用一种形式把第二步产生的错误报告(.dmp)文件发送给你指定的地方。
  d. 查看错误报告
    这里介绍用vc查看错误报告的方法,还可以用windows debug tools这个工具看,方法见5.2 使用windows debug tools查看.dmp文件(错误报告)
    
    查看错误报告需要有三样东西:对应release版的代码,当时编译release版所产生的.exe和.pdb文件。(这两个文件都在编译的输出目录里。)所以当程序发布时,要保留下这两个文件。
    把.dmp(错误报告文件), .pdb, .exe. 代码,在同一目录下,用vc打开.dmp 文件。
    按F5运行,程序即到达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切回代码模式。
  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一系列函数时要注意,这一类函数可能并不能达到你所想要的意图。
    比如下面的代码,两个返回都是false。

代码

char *p = new char[10];
bool b;
b = IsBadReadPtr(p+10, 1);
delete[] p;
char *q = new char[10];
b = IsBadReadPtr(p, 1);

    所以切忌在程序中以IsBadPtr函数来判断是否可以对这个指针进行操作。这些函数只能在调试中使用,或是你确切的知道这些函数的返回值表示的是什么意义的时候。

  4.2 慎用catch(...)
    为了防止程序crash或是解决一个不明白的crash时,大家很容易想到一个 try{}catch(...){}来解决问题。
    的确大部分时间这样不会出问题了,但这个try-catch很有可能隐藏掉在try里面的错误,而当由此错误引起其他错误时,就很难追踪到这个问题了。
    所以建议尽量少用catch(...),如果知道某一块代码会抛出异常,应该用确切的写法。比如catch(CFileException *e), catch(int e)等等。

5. 附录
  5.1 为什么程序crash时调用堆栈是乱的
    当内存被写乱时程序很有可能出现很难定位的crash,比如调用堆栈是乱的,或走到不存在的代码里。这里举一例

代码

class CA
{
public:
CA(){}
~CA(){}
virtual f(){}
};

void show()
{
printf("shown");
}

int main()
{
// 对像被创建删除
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。
    第二块代码可视为一些正常的操作,new了一个q,然后对它进行了一些赋值。
    如果你不明白vtable机制,那你只要知道,最后一行的 “p->f();”会执行变量q所指向的变量所指向的变量所标示的地址。(这里没打错字,是两个“所指向的变量”)
    这里我“心地善良”的给这个值赋上了一个合法的函数地址show。但实际程序中q所指向的变量有可能是任意值,它再指向的变量就更是任意值了。
    那程序就不知道跑哪里去了。如果这个值过于离谱,那算你运气好,程序会立即crash,而你就知道错误位置在哪了。但讨人厌的是,它有可能是一个合法地址,那程序就继续走下去,
    但迟早会crash,并且调用堆栈面目全非(原因牵涉到“调用堆栈的推导”的问题这里就不多说了),
    到时就根本无从知道原来是调用了被删除的p对象而导致的。

  5.2 使用Debugging tools for windows查看.dmp文件(错误报告)
    a. 准备好程序对应的代码,exe文件,pdb文件(编译时在编译输出目录里)
    b. 安装WinDbg
    c. 在winDbg里把Symbol目录设在.pdb所在目录,Image目录设在.exe所在目录,code目录设到代码目录。
    d. 打开.dmp文件
    e. 输入命令.ecxr。(此命令使环境回到崩溃时的状态)
    f. 打开调用堆栈(ALT + F6)查看Crash的位置
    g. 进行分析
简介
  (FinalCheck能检测出的错误列表见附录1)
  BoundsChecker是一个很强大的调试工具。这里只简单介绍如何用它的FinalCheck模式定位比较难定位的错误。
FinalCheck模式简单来说就是BoundsChecker在你的代码里加一些诊断代码来检查平时比较难查出的内存越界,错误的指针使用等。
不过付出的代价就是程序跑起来会比较慢,所以在不用时最好是把FinalCheck模式关掉。特别是发布前。
如何定位导致Crash的代码位置

a. 准备好程序对应的代码,exe文件,pdb文件(编译时在编译输出目录里) b. 安装WinDbg c. 在winDbg里把Symbol目录设在.pdb所在目录,Image目录设在.exe所在目录,code目录设到代码目录。 d. 打开.dmp文件 e. 输入命令.ecxr。(此命令使环境回到崩溃时的状态) f. 打开调用堆栈(ALT + F6)查看Crash的位置 g. 进行...

ZESTRON表界面分析

在Dr. O.K. Wack Chemie GmbH,我们高度重视ZESTRON的表界面分析技术。该技术通过深入研究材料表面与界面的性质,为提升产品质量与可靠性提供了有力支持。ZESTRON的表界面分析不仅涵盖了相变化、化学反应、吸附与解吸等关键领域,还通过高精度仪器如固体表面Zeta电位分析仪等,确保数据准确可靠。这些分析手段对于优化产品配方、改进生产工艺、预防失效问题等具有重要意义,是我们不断提升产品性能与质量的重要工具。表面污染分析包括评估表面上存在的颗粒、残留物或物质。通过利用显微镜、光谱学和色谱法等技术,分析人员可以识别和表征污染物,以确定其成分和来源。这种分析在电子、制药和制造等各个行业中至关重要,以确保产品质量、性能和安全性。了解表面...

Android crash问题分析定位方法

在objdump的帮助下,我们注意到在出错函数的fp-2位置(通常fp对应r11,fp-2则是fp后的第二个内存地址)存储着入参Id。在tombstone中,fp的值为e16ff848,而在stack中fp-2的值为0x8014。这些信息为我们揭示了crash的具体位置,结合源码和汇编代码,就能有效地定位到问题所在。

C++中Crash定位原理与常见案例反汇编分析

首先,理解Crash定位的关键在于理解执行环境。寄存器、栈内存、堆内存的动态变化是分析的基础。定位函数则是通过计算代码偏移量和模块加载基址,同时,行号定位(在编译时启用-g选项的情况下)可以提供宝贵的线索。堆栈回溯是查找崩溃源头的重要手段,但可能由于地址破坏而失去效用。面对Crash,直接从源代码出发...

如何定位导致Crash的代码位置

提供一段代码,能捕获大部分crash消息,不过有些还是没办法: 先将console中的crash信息写入文本,再在下次启动程序时,调用借口将crash信息传回服务器。实例代码如下: - (void)redirectTNLogToDocumentFolder{ NSArray *paths = NSSearchPathF...

Android NDK Tombstone/Crash 分析

将崩溃时的调用内存地址和C++代码一行一行对应起来。总结来说,Android NDK程序的系统调试并不复杂,只要掌握了正确的方法,了解Tombstone文件中关键信息的含义,学会使用addr2line和ndk_stack这两个超级方便的工具,就可以快速定位到导致NDK程序Crash的Bug。但具体的Bug还需要进一步根据业务逻辑来分析代码。

如何面对程序crash

而且能够帮开发者分析出造成 Crash 的原因,本例就是因为是在 WXPersonalCenterViewController 类中没有提供 leaveMessageAndNewsBtnPressed 这个方法。接下来,我们需要做的就是检查一下,在某个类中某个方法是否实现了,或者检查一下方法参数跟调用该方法时参数是否匹配,分分钟就可以定位到具体的代码行,...

如何调试SIGABRT和EXC_BAD_ACCESS引起的crash

1. SIGABRT是处于程序控制状态下的crash,SIGABRT引起的crash是因为系统发现了应用程序正在做一些系统不希望它去做的事情(Exception)。一般情况下,当SIGABRT发生的时候,会现实如下的bug信息:它并不能精确的定位到crash发生在哪个源文件哪行代码中。为了精确的定位,我们可以使用Exception Breakpoint在Exception...

如何定位obj-c野指针随机crash

1.在提交新版本到AppStore时候一定要保留每个版本的.dSYM文件。无法定位crash的代码肯定是.dSYM文件和crash report对应的程序版本不一致。2.由用户反馈的当前版本的crash report可以在iTunesConnect下载。如果是存在设备上的,可以用Organizer导出 3.打开.crash文件,参考Hardware Model确定故障设备是armv6还是...

求助,请各位帮我看看导致app crash的问题在哪里

有多种方式可以定位Crash的程序代码:• Debug模式时,iOSSimulator断点测试定位Crash的堆栈;• 真机连接iTunes查看Crashlog (Debug模式下);• 通过Flurry的错误记录查看;定位之后,就是重新思考程序上下文逻辑,并有理由的预测Crash出现的原因。预测的越多,理解的越深。寻找解决方案的...

如何解决Android应用中的Crash问题

下面介绍一些解决Android应用中的Crash问题的方法。1.分析Crash日志当应用Crash时,系统会生成一个Crash日志,其中包含了Crash的原因和发生的位置等信息。通过分析Crash日志,开发者可以快速定位Crash的原因,并进行相应的修复。通常,开发者可以使用AndroidStudio自带的日志分析工具,或者使用第三方的Crash分析工具...

声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
咋样能快速减肥一月减40斤 混合溶液反应中物质的反应先后有规律吗? 请问小米手环8支持微信消息通知吗? 电脑3代2G内存卡一般多少钱、 什么牌子比较好? 普通2G内存多少钱一个?买两个1G的划算吗?为什么电脑一插两个内存条就... 怀孕三个月做了5次b超对胎儿的影响 怀孕做b超多了对胎儿有影响吗 孕期做了10次b超有害吗 我的亲姐10月16日结婚呢,明天待客呢!我该怎么办呢!我该干啥事情 我姐姐要结婚了,婚礼的时候,当弟弟的要怎么做才算尽到了责任! 泰森能不能打过刘易斯呢? 拳王刘易斯:我是五维拳手,对战巅峰泰森,我也能KO他!是真的吗? 泰森和同一时期的两大拳王(刘易斯、霍利菲尔德)对垒,都未曾取胜,为什么却有这么高的人气? ***和0755950509是什么电话? 0755 -950509 是什么部门的电话? 我弟去深圳市中心找工作去了两天没回来,后来打电话给他女朋友说他被骗了然后匆匆挂了电话…他女朋友看... 拳击手(伦洛克斯·刘易斯■Lennox Lewis■41-2-1 32KO) (41-2-1 32KO)是什么意思?谢谢 我手机贴了钢化膜感觉有一滴水有好像一个泡点点点点小的一点,在屏幕上,看着不爽咋整 0755950509是什么号码?今天miss了这个电话,回播是空号。 0755950509是什么号码? 约书亚二番战靠什么打败鲁伊兹? 正式拳击比赛中刘易斯有被ko 的记录吗? 0755950509是那里的电话,具体是那个单位的电话? 54岁的老拳王最近生活如何? 这个号码是不是骗子的啊,是不是吸金的?0755950509 某陪练竟撑住了泰森的重拳,还KO了刘易斯,他到底是谁? 刚接到一个电话,0755950509,叫我去面试的。打回去打不通。 谁知道0755950509是哪里的号码? 他曾是泰森的金牌陪练,2回合就KO刘易斯了吗? 0755950509这个号码是不是派出所的 《讳疾忌医》告诉我们什么道理? 蔡桓侯不听扁鹊的劝告,最后病死的故事,对我们有什么启发? 广西招生考试院为什么还不能查询录取情况? 广西招生考试院电话号码是多少? 广西招生考试院的电话是多少? 朋友们,在论文中“2003-11-005”是什么意思? 韩非子·难一有哪些成语故事 广西招生考试院行政级别 扁鹊治病这个故事后来演变成一个成语叫什么 如何选双色球第11005期号码 扁鹊见蔡桓公的启示 广西招生考试院怎么查询本科是哪个学校 nike 313791-005查询 扁鹊治病是一则寓言故事,主要讲了什么从 广西招生考试院的介绍 上午11点5分是什么时辰? 我定的火车票是11车厢上005号是什么意思 广西招生考试院户籍代码在哪 什么是讳疾忌医及其典故 广西招生考试院怎么上传照片
  • 焦点

最新推荐

猜你喜欢

热门推荐