windowsclient崩溃分析和调试

本文介绍windows上崩溃分析的一些手段,顺便提多进程调试、死锁等。

1.崩溃分析过程

1.1 确认错误码

不管是用windbg还是用vs。首先应该注意的是错误码,而90%以上的崩溃都是非法訪问。

在非法訪问时。能够看一下訪问的目标地址。

地址是0,或者离0非常近(0x00000008或0xfffffffc)。

一般和空指针相关。假设是一个貌似正常的地址,通常是对象已析构后訪问其数据,或者堆破坏。

1.2确认崩溃相应的C++操作

什么是确认崩溃相应的C++操作:

比方非法訪问,通常得有个mov指令才会触发内存訪问,然后导致崩溃。而mov指针相应于C++的哪一步呢?

比方a->b->c->foo();

在看到源代码时,会定位于这一行,可是,并不清楚是哪一步訪问失败。

所以这个时候要查看相应汇编代码。

大概会有好几个mov,简单的分析就知道是哪一步时訪问失败。

对编码的影响:

这就要求,不要在单个语句中写太复杂的东西比方

x ? b[i] : y > 0 ? c->member[8] : *ptr;

这种代码崩溃。要还原到错误的地方非常难。

虚函数调用:

通常

mov edx, dword ptr [ecx]

mov edx, dword ptr [edx+0x??

]

call edx

意味着虚函数调用。每一行都可能是崩溃位置(在call内崩溃时,vs会标注出下一条语句的位置)。

在第一行崩溃意味着拿到一个非法指针,可能是空,也能够指向非法地址。

在第二行崩溃意味着对象已经析构,ecx指向能够訪问,可是值不正确。所以拿到的虚函数表不正确。

在最后一行崩溃一般另一个崩溃栈,可是看不到栈帧,在vs中相应的栈桢显示一个地址。没其他内容。

也一般意味着对象析构。

对象及析构函数:

析构函数是常常发生崩溃的地方,假设没实用户提供的析构函数,会定位到几行汇编。所以没事,就写个

析构函数吧,至少能定位到是析构函数。

在析构函数外部还会有一大堆汇编代码,里面是对象成员析构的代码。崩溃在里面的时候,难以确认

是哪个对象析构。

假设用指针,在析构函数中主动调用Release或delete,这样能够显示调用,不用去猜是谁在析构,当然

用指针或值对象。在逻辑上各有其优点。在此不表。

假设崩溃位置是call或jmp到某个A::~A()的位置。能够推測到析构的对象的类型是A。

对象析构顺序是从后往前,从子类到基类,依据这点,结合崩溃位置。能够推測谁析构。

利用对象布局,比方成员在对象中的偏移,可能有得于推測谁析构出问题。

能够人为地在对象布局中引入一些填充的字节,使得能看到this对象(线上崩溃没有堆上的数据,由于

截取fulldump并上报有操作上的难度。所以this指向堆上时可能看不到,而在栈上则有可能),有利于分析。

还原上下文:

线上拿到的dump的信息少,不能调试。所以能够依据崩溃所在模块。崩溃在模块中的偏移量,在本地

调试相应的bin,找到相应的模块。偏移量。打上断点,能够在本地还原出崩溃时的运行环境。

当然,

在本地运行到相应位置时不一定崩溃,可是,有了很多其它上下文信息。能够比較easy确定相应的C++操作。

使用IDA:

能够使用IDA让汇编代码更好看,较easy分析流程。

关闭alsr。指定建议模块载入地址:

这样可能使得更easy分析。

可是会使得安全性减少,能够用于小流量版本号。

ln指令:

windbg中ln指令能够依据地址。还原出相应的信息,比方该地址是在某个类的某个方法中。

有时可能会

还原出几个信息:A::foo() + 0x?

?, B::foo1() + 0x??。这就须要自己依据上下文推断了。

代码优化:

代码优化使得分析更难,能够尝试改变一些编译选项,减少优化级别,保留栈桢,关闭应用程序全局优化,

使得在release下的分析easy些。

所见并不是真实:

windbg和vs看到的栈帧可能是假的:可能在中间某一些可能已经乱了,可能栈桢省略使得vs分析的结果不正确。

(通常是vs分析得不正确。另外也有windbg杯具的时候)

对于在中间已经乱掉的栈。能够依据返回地址。栈參数,栈桢省略数据等,又一次还原出栈。只是在90%的情况

下,即使还原出来,也不知道下一步怎么办。

对象还原:

线上崩溃没有堆,能够将感兴趣的对象拷贝复制到栈上(自己得控制深拷贝)。然后崩溃上报中就能够看到

对象的状态了。

(注意代码优化可能使得拷贝无效)

1.3C++上的逻辑

在确定崩溃和C++操作的关系后,就是自己逻辑上的问题了,基本上能遇到的问题都是对象生命周期管理

不当,进而造成非法訪问。

指针的判空能规避一处的非法訪问,可是能够把错误进一步扩散。指针判空。且用且珍惜。

在设计或编码时,应当考虑代码的可调试性。比方chromium中的线程池中,加入任务时,会生成当前调用

信息。和task绑定,以使于定位错误。

1.4堆破坏

基本无解,崩溃现场和引入错误的点相差太远。

仅仅能尽人事,听天命了。

比方,开一下页堆。存在一定概率使得崩溃出现,看人品。

比方。换一个CRT堆。或者自己写个,增强错误检測。

比方。CRT本身。尤其是调试的堆,堆上有些填充信息。使得在看到的时候或多或少叹口气:大概认识这些

填充信息,想要很多其它的信息,难啊。。

比方。能够自己写个调试器,自己插入页堆,或者使用系统的页堆。使得检測自己主动化,然后通过大规模数据

使之重现。

2.其他

多进程调试:

能够通过在

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

建立关心的进程名的项。填上debugger键值,值为调试器路径,使得进程创建时就attach。(gflags也是

改这里)。

可是问题是,有的模块是按需载入的,在这个时候还不能在相应模块中下断点。

另外能够自己在关心的位置加上MessageBox或ATLASSERT之类的代码,等弹出对话框时再attach到相应进程。

activex:

attach方法同理。

可是,IE的多进程模型会使得attach不方便。

在IE9及以上,其进程模型是一个主进程,控制多个tab进程,按一定规则创建tab进程,将任务分派到

tab上。同一个网页打开两次,可能分配到不同的进程上,也可能是同样的进程。在同一个进程中,同一

个activex可能有多个实例,并且每一个实例相应的主线程还不一定是同一个线程。

通常会控制仅仅开一个tab,使得调试更加easy。另外能够开多tab。然后关闭,然后再开,来測试同一个进程

有多外activex实例的情况。更进一步,能够自己调用IWebBrowser2,来模拟很多其它的情况。

np插件:

chrome中这个简单些。一个插件一个进程,多个实例。共享主线程。

还有些开源工具将activex适配为np插件,使得能够在chrome中调用ax。调试。

多机调试:

前面说过,windbg,vs都支持。

死锁:

死锁现场不会是线上问题(能够通过一定手段,使得在线上发生死锁时报告。可是基本上没用过,相应的

手段在线下有玩过)。线下问题通常会有现场,或者能拿到full dump。

一般使用windbg来看,用~*kb或者

这系列的命令看看线程都在干什么。而重点关注的则是WaitForSingleObjectEx之类的调用。

通过分析调用

相应的參数。进一步能还原出,拿到 分发器 对象后不归还的线程是谁。

或者也能够!runaway找到占用CPU

高的线程,然后看看该线程在干什么。线程循环等待,则死锁了。线程一直在那里跑,可能是死循环了。

线下的死锁检測,一般能够向主线程发一个消息来实现。

warning:有可能某个线程拿到分发器对象,可是该线程已经挂掉了。

时间: 2024-10-08 08:08:34

windowsclient崩溃分析和调试的相关文章

windows客户端崩溃分析和调试

本文介绍windows上崩溃分析的一些手段,顺便提多进程调试.死锁等. 1.崩溃分析过程 1.1 确认错误码 无论是用windbg还是用vs,首先应该注意的是错误码,而90%以上的崩溃都是非法访问. 在非法访问时,可以看一下访问的目标地址.地址是0,或者离0很近(0x00000008或0xfffffffc), 一般和空指针相关.如果是一个貌似正常的地址,一般是对象已析构后访问其数据,或者堆破坏. 1.2确认崩溃对应的C++操作 什么是确认崩溃对应的C++操作: 比如非法访问,通常得有个mov指令

iOS 崩溃分析

崩溃统计分析,在APP中是非常常见一种优化APP,发现APP的BUG的方式. 1.异常处理 可通过try catch 方式处理,如果发生异常,会走catch ,最终走fianlly.对一些我们不想他崩溃的地方,可以采取这种方式去处理.但要注意的是,通过这种处理,使用的第三方崩溃将捕捉不到异常信息,不会上报. @try { <#Code that can potentially throw an exception#> } @catch (NSException *exception) { &l

OD分析被调试进程的数据来源

标 题: [原创]OD分析被调试进程的数据来源作 者: fosom时 间: 2013-06-02,23:56:10链 接: http://bbs.pediy.com/showthread.php?t=172815 一直在用OD,但是但是OD的原理是啥?那些数据怎么来的?  于是,就花了几天用OD调试了一下OD,并写了点心得.呵呵. [名称] OD分<vb_highlight>析被调试进程的数据来源 [版本]      .\OllyICE\原版\英文原版\OLLYDBG.EXE v1.10 [工

预防用户流失哪家强?Testin崩溃分析秒杀Flurry

预防用户流失哪家强?Testin崩溃分析秒杀Flurry 2014/11/28 · Testin · 独家评测 大家都知道,每款App或多或少都会存在质量隐患,这是开发者无法避免的问题,但是,你却可以利用开发工具将隐患对用户的影响降低到最低.当用户面对 Bug 频出的 App 又无法直接找到开发者时,他们只能去应用商店里留下差评,再到社交网络里咆哮一番.而这些因为APP质量问题造成的用户流失本是可以避免的. 让我们看看用户流失最常见原因是什么? 对开发者来说,移动App崩溃是最常见的Bug ,这

nginx源码分析--GDB调试

利用gdb[i]调试nginx[ii]和利用gdb调试其它程序没有两样,不过nginx可以是daemon程序,也可以以多进程运行,因此利用gdb调试和平常会有些许不一样.当然,我们可以选择将nginx设置为非daemon模式并以单进程运行,而这需做如下设置即可: daemon off; master_process off; 这是第一种情况: 这种设置下的nginx在gdb下调试很普通,过程可以[iii]是这样: 执行命令: [email protected]:/usr/local/nginx/

系统崩溃分析

平台:MT55 F3700 现象:压测发现部分死机问题,遥控器无法待机,但主页.上下左右OK等按键仍起作用,无法播放视频,各信源下黑屏无法播放图像 关键log: 2014-06-28 14:50:45┇01-01 08:56:56.605   853  1005 F libc    : Fatal signal 11 (SIGSEGV) at 0x00000558 (code=1) 2014-06-28 14:50:45┇01-01 08:56:56.672   985  1266 I Acti

如何分析、调试微服务系统的故障?

基于研究论文<Fault Analysis and Debugging of Microservice Systems: Industrial Survey, Benchmark System, and Empirical Study>(作者:周翔.彭鑫.谢涛.孙军.冀超.李文海.丁丹)形成本文.该论文由复旦大学计算机科学技术学院彭鑫教授领导的智能化软件开发 CodeWisdom 团队与北京大学谢涛教授.新加坡管理大学孙军副教授合作完成,并被评选为软件工程领域的国际旗帜期刊.CCF A 类期刊

Android APP native 崩溃分析之令人困惑的 backtrace

完美无缺的代码逻辑,一定能产生完美无缺的程序吗?答案是否定的.从软件的层面来看,也许只有二进制才永远不会欺骗你. 现象 近期,业务方反馈了一个奇怪的崩溃问题,认为信息不足,无法解决. Signal: 11 (SIGSEGV), Code: 1 (SEGV_MAPERR) r0 993ff520 r1 dc3170c4 r2 00000000 r3 dabe3e08 r4 993ff520 r5 00000005 r6 00000290 r7 000007ac r8 e83253a0 r9 000

Windows内核分析——内核调试机制的实现(NtCreateDebugObject、DbgkpPostFakeProcessCreateMessages、DbgkpPostFakeThreadMessages分析)

本文主要分析内核中与调试相关的几个内核函数. 首先是NtCreateDebugObject函数,用于创建一个内核调试对象,分析程序可知,其实只是一层对ObCreateObject的封装,并初始化一些结构成员而已. 我后面会写一些与window对象管理方面的笔记,会分析到对象的创建过程. //来自WRK1.2NTSTATUS NtCreateDebugObject ( OUT PHANDLE DebugObjectHandle, IN ACCESS_MASK DesiredAccess, IN P