怎样分析crash dump

作者&投稿:成诚 (若有异议请与网页底部的电邮联系)
如何使用Windbg分析崩溃dump~

需要为Windbg软件设置符号表路径,作为蓝屏原因分析数据库,否则软件将没有作用。单击File--选择Symbol File Path,在弹出的对话框Symbol Path文本框中输入SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols,单击OK。



设置完毕后单击File--选择Open Crash Dump来打开蓝屏文件,在弹出的对话框中点选到C:\Windows\Minidump文件夹,单击我们要分析的蓝屏文件,单击打开。


在弹出的对话框Save Information for workspace?(是否保存信息到工作区)中单击Yes。(如果下次不想再被提示,可以勾选Don't ask again in the WinDbg session)。


接下来就是对文件进行分析,这需要一定的经验和知识。这里我们着重可以看一下System Uptime(开机时间)和Probably Caused By(可能引起故障的原因是)。


需要进一步分析,可以单击!analyze -v,此时我们可以从中提取到蓝屏错误代码和引起蓝屏的程序名称,再通过网络搜索这些程序名和代码等方式弄清原因。


1、 打开Dump格式文件
打开WinDbg,通过菜单[File] à [Open Crash dump] 选择dump文件打开,也可通过CMD打开Dos命令窗口,切换到WinDbg所在目录,利用命令:
WinDbg –z “D:/Lines2009-7-25-22-20-33-900.dmp”
-z表示路径


图1.1 利用WinDbg打开dump文件

本文编写了一个简单能产生除数为0异常的程序,让其运行,产生崩溃,通过drwtsn产生dmp文件,然后通过windbg分析dmp文件,定位程序bug。
目的:学习windbg基本功能使用。
程序源代码:
void Crash(void)
{
int i = 1;
int j = 0;
i /= j;

}
void main(void)
{

Crash();

}

编译环境:vc++6.0
编译器设置:




这一步设置,要求对release版本不使用优化,如果使用优化,上面源代码中Crash(void)函数将不被汇编。

这一步设置,产生release版本的调试符号表,为后续定位错误准备。

Memory错误
在内核中,内存是以cache的形式组织的,每个对象类型对应一个cache,如(inod_cache,dentry_cache, buffer_head,vm_area_strutct等);每个cache包含多个slab(slab由一个或多个页组成,这些页物理上是连续的);每个slab包含多个初始化的对象。
Cache可以分为两类【kmalloc使用的和其他】,当然他们是用同一个函数创建的。

1.Crash> Kmem -s
CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE
ee2bb0c0 scsi_sense_cache 120 2 32 1 4k
ee2bbac0 scsi_cmd_cache 176 2 22 1 4k
ee000c60 size-4194304 4194304 0 0 0 4096k
ee000bc0 size-2097152 2097152 0 0 0 2048k
ee000b20 size-1048576 1048576 1 1 1 1024k
ee000a80 size-524288 524288 0 0 0 512k
ee0009e0 size-262144 262144 0 0 0 256k
ee000940 size-131072 131072 1 1 1 128k
ee0008a0 size-65536 65536 2 2 2 64k
ee000800 size-32768 32768 1 1 1 32k
ee000760 size-16384 16384 9 9 9 16k
ee0006c0 size-8192 8192 10 10 10 8k
ee000620 size-4096 4096 26 44 44 4k
ee000580 size-2048 2072 53 60 20 8k
ee0004e0 size-1024 1048 332 343 49 8k
ee000440 size-512 536 771 798 114 4k
ee0003a0 size-256 280 54 84 6 4k
ee000300 size-192 216 734 756 42 4k
ee000260 size-128 152 2301 2314 89 4k
ee0001c0 size-32 56 13439 13668 204 4k
ee000120 size-96 120 1067 1120 35 4k
ee000080 size-64 88 3137 3168 72 4k

调用函数kmalloc(xxx)得到的memory都来名字为size-xx的cache.

2.CONFIG_DEBUG_SLAB
为便于调试,在每个对象可以添加SLAB_RED_ZONE,添加这块内存的最后使用者SLAB_STORE_USER,且用SLAB_POISON初始化对象。
这些特殊的元素是什么?
Include/linux/poison.h
/*
*Magic nums for obj red zoning.
*Placed in the first word before and the first word after an obj.
*/
#define RED_INACTIVE 0x09F911029D74E35BULL /*when obj is inactive */
#define RED_ACTIVE 0xD84156C5635688C0ULL /*when obj is active */

/*...and for poisoning */
#define POISON_INUSE 0x5a /*for use-uninitialised poisoning */
#definePOISON_FREE 0x6b /* foruse-after-free poisoning */
#define POISON_END 0xa5 /*end-byte of poisoning */
3.log | tail xxx
当slab出错时,会把cachename/ objecet的开始地址(没有考虑redzone)
redzone的内容/lastuser和object的内容都会打印出来,另外还包含该对象前后对象的信息。
[ 45.501503:0] Slab corruption (Not tainted): size-64 start=e74b3398,len=64
[ 45.508518:0] Redzone: 0x9f911029d74e35b/0x9f911029d74e35b.
[ 45.514118:0] Last user: [<c03446e8>](__DWC_FREE+0x1c/0x20)
[ 45.519816:0] 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b d8 b0 54 e8 kkkkkkkkkkkk..T.

[ 45.527633:0] Prev obj: start=e74b3340, len=64
[ 45.532108:0] Redzone: 0xd84156c5635688c0/0xd84156c5635688c0.
[ 45.537880:0] Last user:[<c045ad78>](binder_get_ref_for_node+0x6c/0x204)
[ 45.544777:0] 000: 47 34 00 00 2c 8b e5 e7 00 00 00 00 00 00 00 00 G4..,...........
[ 45.552584:0] 010: f1 31 4b e7 50 83 e5 e7 10 46 61 e7 00 00 00 00 .1K.P....Fa.....

[ 45.560393:0] Next obj: start=e74b33f0, len=64
[ 45.564866:0] Redzone: 0xd84156c5635688c0/0xd84156c5635688c0.
[ 45.570636:0] Last user: [<c004df30>](copy_creds+0x108/0x1e4)
[ 45.576479:0] 000: 01 00 00 00 5a 5a 5a 5a 00 00 00 00 5a 5a 5a 5a ....ZZZZ....ZZZZ
[ 45.584281:0] 010: ad 4e ad de ff ff ff ff ff ff ff ff 00 00 00 00 .N..............

[ 45.592154:0] ------------[ cut here ]------------
[ 45.596974:0] kernel BUG atmm/slab.c:2037!
[ 45.601188:0] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
[ 45.607223:0] Modules linked in:
[ 45.610516:0] CPU: 0 Not tainted (3.4.0-gc37fe8c-dirty #657)
[ 45.616585:0] PC is at check_poison_obj+0x194/0x1b4
[ 45.621512:0] LR is at console_unlock+0x1c0/0x1d4
[ 45.626260:0] pc : [<c00d46f8>] lr : [<c0028fe0>] psr: 60000093
[ 45.626294:0] sp : e58e1c68 ip : e58e1a40 fp : e58e1c9c
[ 45.638134:0] r10: e74b3398 r9 : 00000008 r8 : e74b3338
[ 45.643565:0] r7 : 00000040 r6 : e74b3000 r5 : e74b33e8 r4 :ee000080
[ 45.650296:0] r3 : 00000001 r2 : 00000010 r1 : 00000020 r0 :e74b33f0
[ 45.657033:0] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
[ 45.664635:0] Control: 10c53c7d Table: af4e404a DAC: 00000015

kmem-S size-64
从打印的信息siize-64start=e74b3398, 得知出问题的是cache:size-64,地址为
e74b3390.
4.Crash> kmem -S cache name
crash>kmem -S size-64 | grep e74b3390
[e74b3390]
crash>rd e74b3390 0x64
e74b3390: 9d74e35b 09f91102 6b6b6b6b6b6b6b6b [.t.....kkkkkkkk
e74b33a0: 6b6b6b6b 6b6b6b6b 6b6b6b6b 6b6b6b6b kkkkkkkkkkkkkkkk
e74b33b0: 6b6b6b6b e854b0d8 6b6b6b6b6b6b6b6b kkkk..T.kkkkkkkk
e74b33c0: 6b6b6b6b 6b6b6b6b 6b6b6b6b 6b6b6b6b kkkkkkkkkkkkkkkk
e74b33d0: 6b6b6b6b a56b6b6b 9d74e35b09f91102 kkkkkkk.[.t.....
e74b33e0: ff000000 c03446e8

从出问题的这个object的用于debug的信息可知:
redzone: 9d74e35b 09f91102 :RED_INACTIVE
poisondata: 6b : POISON_FREE
usercall : c03446e8
5.last caller
最后操作这块内存的函数为:
crash>dis -r c03446e8
0xc03446cc<__DWC_FREE>: mov r12, sp
0xc03446d0<__DWC_FREE+4>: push {r11, r12, lr, pc}
0xc03446d4<__DWC_FREE+8>: sub r11, r12, #4
0xc03446d8<__DWC_FREE+12>: stmfd sp!, {lr}
0xc03446dc<__DWC_FREE+16>: ldmfd sp!, {lr}
0xc03446e0<__DWC_FREE+20>: mov r0, r1
0xc03446e4<__DWC_FREE+24>: bl 0xc00d51fc <kfree>
0xc03446e8<__DWC_FREE+28>: ldm sp, {r11, sp, pc}

结合如下的backtrace,可知问题就是从slab申请的一个对象,但发现其中的元素不对(不是0x6b,却出现了e854b0d8,所以crash)
[ 45.596974:0] kernel BUG at mm/slab.c:2037!
[ 46.736498:0] Backtrace:
[ 46.739243:0] [<c00d4564>] (check_poison_obj+0x0/0x1b4) from[<c00d4f84>] (cache_alloc_debugcheck_after+0x3c/0x1a0)
[ 46.749743:0] [<c00d4f48>](cache_alloc_debugcheck_after+0x0/0x1a0) from [<c00d6df0>](__kmalloc+0x140/0x234)
[ 46.759680:0] r7:00000038 r6:00008020 r5:a0000093 r4:ee000080
[ 46.765709:0] [<c00d6cb0>] (__kmalloc+0x0/0x234) from[<c03448c0>] (__DWC_ALLOC_ATOMIC+0x20/0x24)
[ 46.774674:0] [<c03448a0>] (__DWC_ALLOC_ATOMIC+0x0/0x24) from[<c0340dbc>] (dwc_otg_hcd_urb_alloc+0x30/0x40)
[ 46.784585:0] [<c0340d8c>] (dwc_otg_hcd_urb_alloc+0x0/0x40)from [<c0352f00>] (urb_enqueue+0xf0/0x258)
[ 46.793916:0] r4:db95faa8 r3:00000003
[ 46.797796:0] [<c0352e10>] (urb_enqueue+0x0/0x258) from[<c031f32c>] (usb_hcd_submit_urb+0x5c4/0x6a4)
[ 46.807069:0] [<c031ed68>] (usb_hcd_submit_urb+0x0/0x6a4) from[<c031fa60>] (usb_submit_urb+0x2a0/0x2bc)
[ 46.816603:0] [<c031f7c0>] (usb_submit_urb+0x0/0x2bc) from[<c03208bc>] (usb_sg_wait+0x4c/0x138)

6.解决问题
从上面的分析可知,问题是memoryfree后,代码又操作了这块内存。
现在问题是__DWC_FREE最后操作了这块内存,__DWC_FREE只是封装了kfree,
如果直接使用kfree,通过SLAB_STORE_USER就可以知道那个函数调用了kfree,
进而知道申请的对象类型,看那个该对象类型的那个成员被赋值,就可以在代码中搜索。

如该例知道了类型为dwc_otg_qtd_t,且成员qh在内存释放后被赋值,就可以在代码中详细查找,分析。
crash>dwc_otg_qtd_t e74b3398
structdwc_otg_qtd_t {
data_toggle= 0x6b,
control_phase= (DWC_OTG_CONTROL_DATA | DWC_OTG_CONTROL_STATUS | unknown:1802201960),
complete_split= 0x6b,
ssplit_out_xfer_count= 0x6b6b6b6b,
error_count= 0x6b,
isoc_frame_index= 0x6b6b,
isoc_split_pos= 0x6b,
isoc_split_offset= 0x6b6b,
urb= 0x6b6b6b6b,
qh= 0xe854b0d8,
qtd_list_entry= {
cqe_next= 0x6b6b6b6b,
cqe_prev= 0x6b6b6b6b
},
in_process= 0x6b,
n_desc= 0x6b,
isoc_frame_index_last= 0x6b6b
}
在相关的代码中搜索哪里操作了数据结构dwc_otg_qtd_t的qh成员。


0



塘沽区15885375613: 如何分析dump文件 -
益委和血: 1、 打开Dump格式文件 打开WinDbg,通过菜单[File] à [Open Crash dump] 选择dump文件打开,也可通过CMD打开Dos命令窗口,切换到WinDbg所在目录,利用命令: WinDbg –z “D:/Lines2009-7-25-22-20-33-900.dmp” -z表示路径图1.1 ...

塘沽区15885375613: linux 下面的Crash dump是什么意思? -
益委和血: 就是说一个后台进程(deamon)死了(crash),需要重启.在重启前,kernel会把内存里的相关信息写到文件里,就是dump文件.研发根据dump文件,可以找出进程crash的原因,进行修复.

塘沽区15885375613: 如何捕捉程序异常/crash 并生成 dump 文件 -
益委和血: 程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件.步骤:1) 打开WinDBG并将之Attach 到crash的程序进程2) 输入产生dump 文件的命令 ...

塘沽区15885375613: win7 appcrash问题怎么解决 -
益委和血: 1、Crash发生后,系统会生成dump文件,Dump文件是进程的内存镜像,Win7上的dump文件一般保存C:\Windows\Minidump目录下,需要管理员权限才可以访问.2、要分析Crash通过dump文件入手,需要安装windbg,在Windbg中,通过File→Open Crash Dump菜单可以打开dump文件进行分析,3、载入dump文件后,在windbg最下面的命令栏中输入:!analyze -v 进行分析即可.!表示是windbg的扩展命令,analyze是扩展的命令, -v是参数.

塘沽区15885375613: 如何使用Windbg分析崩溃dump -
益委和血: 右击“计算机”-“属性”-“高级系统设置”-“高级”-“启动和故障恢复”设置 2.提取蓝屏文件"C:WINDOWSMinidump"dump文件及"C:WINDOWS"MEMERY.DUMP 3.下载安装windbg 4.启动"windbg"-点击"File"-"OpenCrashDump...

塘沽区15885375613: 如何分析android crash log -
益委和血: android framework分为java和native两层native运行于C的runtime,高效.一般java层只是封装,通过jni访问native底层HAL,driver的crash也会导致上层的crash ‍,有效利用Log信息并对其进行分析与实时的监控管理,对于分析Android手机发...

塘沽区15885375613: 手机出现qualcomm crashdump mode 是什么意思? -
益委和血: Qualcomm Crashdump Mode是一种进入恢复模式的方式,通常在手机遇到严重问题时自动启动.它是由Qualcomm公司提供的一种测试和调试工具,可以帮助开发人员诊断和解决软件或硬件错误.当设备处于Crashdump Mode时,用户无法访问设备存储或执行任何操作.为了解决问题,用户需要使用特定软件或刷入特定的固件来恢复设备.

塘沽区15885375613: 一加为什么会出现crashdumpmode
益委和血: 一加手机只要是 出现 qualcomm crashdump mode那么恭喜你百分百是CPU虚焊 要拆机的, 处理器那部分拆出来再装回去, 原理很简单.一加手机(OnePlus)成立于2013年,总部位于中国深圳.一加手机创立的初衷希望以“只做精品”的形式为用户打造最好的安卓手机产品,与世界分享品质科技.

塘沽区15885375613: DUMP文件分析,该怎么解决 -
益委和血: 1、Dump文件是进程的内存镜像,Win7上的dump文件一般保存C:\Windows\Minidump目录下,需要管理员权限才可以访问.2、要分析dump文件,需要安装windbg,在Windbg中,通过File→Open Crash Dump菜单可以打开dump文件进行分析,如下图所示:载入dump文件后,在windbg最下面的命令栏中输入:!analyze -v 进行分析即可.!表示是windbg的扩展命令,analyze是扩展的命令, -v是参数.

塘沽区15885375613: crash dump是什么意思 -
益委和血: 崩溃转储,就启动一个宕机转存,内存倾倒

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网