示范如何使用windbg分析转储文件

对于上架的windows store应用程序,微软提供了反馈机制让用户在程序崩溃的时候可以自动上传迷你转储(mini dump)文件。这些dump文件对于分析用户遇到的问题是相当有帮助的,这里我就如何使用windbg分析转储文件来做一个示范,我的目标是让即使是没用过windbg的人也能够使用它来分析转储文件,所以如果你发现文章中哪里有让你迷惑的地方,请告诉我。:)

首先,你需要有windows debugger tools,也就是windbg。这是一个强大的系统级调试工具,它附属于Windows WDK和Windows SDK安装包中,WDK这玩意儿太小众了,我们这边暂且不提,所以安装windbg的最佳办法就是安装Windows SDK了,Windows SDK很大,你在安装的时候你可以选择只安装Debugging Tools for Windows。Windows SDK for Windows 8.1的下载地址如下:

http://msdn.microsoft.com/en-US/windows/desktop/bg162891

��安装完windbg以后,我们就可以来分析转储文件了。但是且慢,转储文件呢,转储文件到哪里去找? 如果你找不到的话,那么请随我来。当你的windows store应用上架以后,你就可以看到一个“报告”按钮。

点击这个“报告”按钮,你就可以看到应用程序的统计数据以及左边菜单栏中的“质量”链接:

点击“质量”链接你会看到程序关于质量方面统计数据,这里直接忽略前面的三项看第四项“最常见的崩溃情况”,这里就提供了客户上传的转储文件。

选取你想要看的转储文件,然后下载,下载的文件是一个cab格式的压缩包,将它解压缩就得到了dmp后缀的转储文件了。我们会在这里演示两个转储文件的分析。

用windbg打开第一个转储文件,windbg会在命令窗口中显示报错的代码,这通常是在系统的组件中,对我们查抄问题并没有帮助。比如以下就是载入转储文件后显示的内容:

Windows 8.1 Version 9600 MP (4 procs) Free x86 compatible

Product: WinNt, suite: SingleUserTS Personal

Built by: 6.3.9600.16384 (winblue_rtm.130821-1623)

Machine Name:

Debug session time: Tue Jan 28 21:19:13.000 2014 (UTC + 8:00)

System Uptime: 0 days 13:25:15.561

Process Uptime: 0 days 0:06:15.000

................................................................

................................................................

.............................................

Loading unloaded module list

........

This dump file has an exception of interest stored in it.

The stored exception information can be accessed via .ecxr.

(2054.2efc): Unknown exception - code c000027b (first/second chance not available)

eax=aaaaaaaa ebx=00000000 ecx=00000000 edx=00000000 esi=050eeea0 edi=aaaaaaaa

eip=75789bcf esp=050eee5c ebp=050eeef8 iopl=0 nv up ei pl nz ac po nc

cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212

combase!RoFailFastWithErrorContextInternal+0x10a:

75789bcf 6a03 push 3

为了帮助我们查看转储文件中的内容,首先我们需要告诉windbg到哪里去找符号(symbol)文件,你可以在windbg的命令栏中依次键入以下命令:

0:004> .sympath+ srv*http://msdl.microsoft.com/download/symbols

Symbol search path is: srv*http://msdl.microsoft.com/download/symbols

Expanded Symbol search path is: srv*http://msdl.microsoft.com/download/symbols

************* Symbol Path validation summary **************

Response Time (ms) Location

Deferred srv*http://msdl.microsoft.com/download/symbols

0:004> .reload

................................................................

................................................................

.............................................

Loading unloaded module list

........

通常你也需要用以上命令加入你的应用程序的符号文件路径,符号文件的后缀名为pdb,通常由编译器在生成最后的二进制文件时一起生成,所以这里你可以将路径设为Visual Studio输出可执行文件的目录。注意这里的pdb文件必须和你要查看的转储文件使用的可执行文件版本完全一致,所以为了方便起见,你最好妥善保留每一个需要维护的版本的pdb文件。

首先我们用k命令来看一看出问题时的调用堆栈(call stack):

0:004> k

ChildEBP RetAddr

050eeef8 5fa44fec combase!RoFailFastWithErrorContextInternal+0x10a

050eef20 5fa44c62 Windows_UI_Xaml!DirectUI::ErrorHelper::ProcessUnhandledError+0xb8

050eef84 5fa44af6 Windows_UI_Xaml!DirectUI::FinalUnhandledErrorDetectedRegistration::OnFinalUnhandledErrorDetected+0xad

050eef98 6ab37e13 Windows_UI_Xaml!Microsoft::WRL::Details::InvokeHelper<Microsoft::WRL::Implements<Microsoft::WRL::RuntimeClassFlags<2>,Windows::Foundation::IEventHandler<Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs *>,Microsoft::WRL::FtmBase,Microsoft::WRL::Details::Nil,Microsoft::WRL::Details::Nil,Microsoft::WRL::Details::Nil,Microsoft::WRL::Details::Nil,Microsoft::WRL::Details::Nil,Microsoft::WRL::Details::Nil,Microsoft::WRL::Details::Nil>,long (__stdcall*)(IInspectable *,Windows::ApplicationModel::Core::IUnhandledErrorDetectedEventArgs *),2>::Invoke+0x12

050eefb4 6ab37e44 twinapi_appcore!Windows::Internal::Details::GitInvokeHelper<Windows::Foundation::IEventHandler<Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs *>,Windows::Internal::GitPtr,2>::Invoke+0x3c

050eefcc 6ab30d3e twinapi_appcore!Windows::ApplicationModel::Core::UnhandledErrorInvokeHelper::Invoke+0x19

从调用栈中可以看出,这时候系统已经在处理产生的异常(exception),这完全不是我们所想要的,我们想要看到的是这个异常是什么以及是谁报出来的。请不要着急,我们可以先看一下最后一个异常的详细信息,这通常就是我们想要找的异常:

0:004> .exr -1

ExceptionAddress: 5fa44fec (Windows_UI_Xaml!DirectUI::ErrorHelper::ProcessUnhandledError+0x000000b8)

ExceptionCode: c000027b

ExceptionFlags: 00000001

NumberParameters: 2

Parameter[0]: 1089daa0

Parameter[1]: 00000001

这里给出了异常的错误代码,快看一下这是什么错误:

0:004> !error c000027b

Error code: (NTSTATUS) 0xc000027b (3221226107) - An application-internal exception has occurred.

天阿,应用程序内部异常,这等于还是什么都不知道么。别急,看到第一个参数了没有,这个参数里面包含了进一步的信息,让我们一步一步来把其中的秘密给找出来。

第一个参数0x1089daa0实质上是一个内部结构的指针,这个内部结构通常有两个版本,首先我们需要确定这里用的是哪一个版本,我们用以下命令得到结构头部分的输出然后进行格式化:

0:004> dt 1089daa0 combase!_STOWED_EXCEPTION_INFORMATION_HEADER*

0x171e0f74

+0x000 Size : 0x20

+0x004 Signature : 0x53453031

0:004> .formats 0x53453031

Evaluate expression:

Hex: 53453031

Decimal: 1397043249

Octal: 12321230061

Binary: 01010011 01000101 00110000 00110001

Chars: SE01

Time: Wed Apr 09 19:34:09 2014

Float: low 8.46917e+011 high 0

Double: 6.90231e-315

这里可以看出这是一个SE01版本的结构,所以我们可以重新解析地址0x1089daa0:

0:004> dt 1089daa0 combase!_STOWED_EXCEPTION_INFORMATION_V1*

0x171e0f74

+0x000 Header : _STOWED_EXCEPTION_INFORMATION_HEADER

+0x008 ResultCode : 80070057

+0x00c ExceptionForm : 0y01

+0x00c ThreadId : 0y000000000000000000101110111111 (0xbbf)

+0x010 ExceptionAddress : (null)

+0x014 StackTraceWordSize : 4

+0x018 StackTraceWords : 0x30

+0x01c StackTrace : 0x171dff6c Void

+0x010 ErrorText : (null)

当然如果输出的结果是SE02的话,那么就需要使用_STOWED_EXCEPTION_INFORMATION_V2这个数据结构了。这里我们终于看到了真正的错误代码80070057,这是一个参数错误:

0:004> !error 80070057

Error code: (HRESULT) 0x80070057 (2147942487) - The parameter is incorrect.

那么它是在什么地方发生的呢,_STOWED_EXCEPTION_INFORMATION_V1结构也给出了调用栈的指针0x171dff6c,让我们看看调用栈是什么样的:

0:004> dps 0x171dff6c L30

171dff6c 5f8a8b50 Windows_UI_Xaml!DirectUI::Selector::OnSelectedIndexChanged+0x3f8b1c

171dff70 5f4b0020 Windows_UI_Xaml!DirectUI::Selector::OnPropertyChanged+0x7d

171dff74 5fa80fc7 Windows_UI_Xaml!DirectUI::FlipView::OnPropertyChanged+0x59

171dff78 5f73641f Windows_UI_Xaml!DirectUI::DependencyObject::UpdateEffectiveValue+0x122

171dff7c 5f7361c7 Windows_UI_Xaml!DirectUI::DependencyObject::SetValueInternal+0x4f5

171dff80 5f4af548 Windows_UI_Xaml!DirectUI::SelectorGenerated::put_SelectedIndex+0x6d

171dff84 5fa81fa8 Windows_UI_Xaml!DirectUI::FlipView::UpdateSelectedIndex+0x13

171dff88 5fa7f9c5 Windows_UI_Xaml!DirectUI::FlipView::MovePrevious+0x53

171dff8c 5fa80e92 Windows_UI_Xaml!DirectUI::FlipView::OnPointerWheelChanged+0x211

171dff90 5fbda3ea Windows_UI_Xaml!DirectUI::ControlGenerated::OnPointerWheelChangedProtected+0x59

171dff94 5f860630 Windows_UI_Xaml!DirectUI::Control::FireEvent+0x4c1b36

171dff98 5f39ea11 Windows_UI_Xaml!DirectUI::DXamlCore::FireEvent+0x200

171dff9c 5f39db3d Windows_UI_Xaml!AgCoreCallbacks::FireEvent+0x40

171dffa0 5f39da7b Windows_UI_Xaml!CCoreServices::CLR_FireEvent+0x9b

171dffa4 5f39d9c1 Windows_UI_Xaml!CommonBrowserHost::CLR_FireEvent+0x20

171dffa8 5f39d2f3 Windows_UI_Xaml!CControlBase::ScriptCallback+0x9a

通过观察这个调用栈关系,结果就很明显了,这个问题发生在FlipView的SelectedIndex属性发生变化的时候,错误原因是参数不对,也就是说赋给SelectedIndex的值有问题,我们需要找到给SelectedIndex赋值的地方,看看是不是有不合适的数据赋给了它。

接下来让我们看一看另一个转储文件,同样,在windbg中加载转储文件,设置symbol路径以后,先用k命令看一下当前的调用栈:

0:004> k

ChildEBP RetAddr

051af5fc 7696a5bd combase!RoFailFastWithErrorContextInternal+0x10a

051af610 60ee5863 combase!RoFailFastWithErrorContext+0x11

051af630 60ee58b3 twinapi_appcore!Windows::ApplicationModel::Core::CoreApplication::ForwardLocalError+0x77

051af648 7696a1e4 twinapi_appcore!Windows::ApplicationModel::Core::CoreApplicationFactory::ForwardLocalError+0x30

051af690 7696a6ac combase!CallErrorForwarder+0x9d

051af69c 723c2d42 combase!RoReportUnhandledError+0x18

051af6fc 7245ffc1 mscorlib_ni+0x9b2d42

051af71c 7245fd35 mscorlib_ni+0xa4ffc1

051af74c 5b09f9df mscorlib_ni+0xa4fd35

051af83c 5b09f965 System_Runtime_WindowsRuntime_ni+0x1f9df

051af8a4 71d33156 System_Runtime_WindowsRuntime_ni+0x1f965

051af8b8 5b09f934 mscorlib_ni+0x323156

051af8d4 5b1aff16 System_Runtime_WindowsRuntime_ni+0x1f934

051af8f8 72b92a36 Windows_UI_ni+0x9ff16

051af978 5d783fb5 clr!COMToCLRDispatchHelper+0x28

051af9f8 5d7837e7 Windows_UI!Windows::UI::Core::CDispatcher::ProcessInvokeItem+0x4d0

(Inline) -------- Windows_UI!Windows::UI::Core::CDispatcher::ProcessMessage+0xffffff8a

051afa94 5d7816dc Windows_UI!Windows::UI::Core::CDispatcher::WaitAndProcessMessages+0x271

051afaf4 5c949931 Windows_UI!Windows::UI::Core::CDispatcher::ProcessEvents+0x60

051afb3c 60ebf45e Windows_UI_Xaml!DirectUI::FrameworkView::Run+0x5e

051afb48 60ebf322

显然,这也不是我们想要看的调用栈,那么像第一个例子一样,看看最近的那个异常:

0:004> .exr -1

ExceptionAddress: 7696a5bd (combase!RoFailFastWithErrorContext+0x00000011)

ExceptionCode: c000027b

ExceptionFlags: 00000001

NumberParameters: 2

Parameter[0]: 051af574

Parameter[1]: 00000001

错误码仍然是c000027b。这次我们不怕了,因为我们从前面的例子中学了一招,按照前面的办法重新做一遍:

0:004> dt 051af574 combase!_STOWED_EXCEPTION_INFORMATION_HEADER*

0x0d331aac

+0x000 Size : 0x20

+0x004 Signature : 0x53453031

0:004> .formats 0x53453031

Evaluate expression:

Hex: 53453031

Decimal: 1397043249

Octal: 12321230061

Binary: 01010011 01000101 00110000 00110001

Chars: SE01

Time: Wed Apr 09 19:34:09 2014

Float: low 8.46917e+011 high 0

Double: 6.90231e-315

0:004> dt 051af574 combase!_STOWED_EXCEPTION_INFORMATION_V1*

0x0d331aac

+0x000 Header : _STOWED_EXCEPTION_INFORMATION_HEADER

+0x008 ResultCode : 80070102

+0x00c ExceptionForm : 0y01

+0x00c ThreadId : 0y000000000000000000001101000110 (0x346)

+0x010 ExceptionAddress : 0x768ea9d7 Void

+0x014 StackTraceWordSize : 4

+0x018 StackTraceWords : 0xa

+0x01c StackTrace : 0x076dc300 Void

+0x010 ErrorText : 0x768ea9d7 "趍ﯰ???"

0:004> !error 80070102

Error code: (HRESULT) 0x80070102 (2147942658) - The wait operation timed out.

0:004> dps 0x076dc300 La

076dc300 768ff132 combase!RoOriginateLanguageException+0x3b

076dc304 723c2c6a mscorlib_ni+0x9b2c6a

076dc308 7245ff62 mscorlib_ni+0xa4ff62

076dc30c 7245fd21 mscorlib_ni+0xa4fd21

076dc310 5b09f9df System_Runtime_WindowsRuntime_ni+0x1f9df

076dc314 5b09f965 System_Runtime_WindowsRuntime_ni+0x1f965

076dc318 71d33156 mscorlib_ni+0x323156

076dc31c 5b09f934 System_Runtime_WindowsRuntime_ni+0x1f934

076dc320 5b1aff16 Windows_UI_ni+0x9ff16

076dc324 72b92a36 clr!COMToCLRDispatchHelper+0x28

这回错误代码找到了,是0x80070102,但是调用栈中显示的怎么仍然是一个无意义的RoOriginateLanguageException呢?别急,这说明这个异常是在.net代码中产生的,我们用调试.net代码的插件sos来看一看,首先,在windbg中加载sos插件:

0:004> .loadby sos clr

接下来就可以使用sos的命令PrintException (pe)来查看.net代码报出来的异常了:

0:004> !sos.pe

Exception object: 02807538

Exception type: System.Exception

Message: <Invalid Object>

InnerException: <none>

StackTrace (generated):

SP IP Function

051AF710 71D9D17A mscorlib_ni!System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)+0x5e

051AF720 71D9D115 mscorlib_ni!System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)+0x35

051AF72C 04E9DA2D OurCalendar!OurCalendar.ViewModel.LoginViewModel+<Login>d__7.MoveNext()+0x29d

051AF814 7251458F mscorlib_ni!System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__4(System.Object)+0x33

051AF81C 5B09F994 System_Runtime_WindowsRuntime_ni!System.Threading.WinRTSynchronizationContext+Invoker.InvokeCore()+0x24

StackTraceString: <none>

HResult: 80070102

接下来的情况就和明显了,这是在应用程序的代码中报的错,当然,我们的代码实际上是没有MoveNext这个函数的,这个函数是编译器在编译异函数Login的异步处理的时候自动生成的,所以下一步我们就应该去查看OurCalendar.ViewModel.LoginViewModel.Login函数中为什么会报这个异常了。

以上就是我们在分析用户报告的Windows Store应用崩溃时常用的办法。这里我用两个实际的例子做了一个演示,分别针对Winrt的本地代码中报出的异常和.NET代码中报出的异常,希望对大家提高Window Store应用的稳定性有所帮助。

时间: 2024-11-10 01:11:36

示范如何使用windbg分析转储文件的相关文章

WinDbg分析DMP文件方法完全攻略

前言:在C++实际开发过程中,开发出来的程序,一般情况下由开发人员进行单元测试,然后移交给测试人员进行测试.在开发人员测试出现的bug,我们可以直接在本地进行调试.如果测试人员测试出崩溃级别的bug,如果我们需要调试往往借助于vs提供的Remote Debugger工具进行远程调试(关于vs2010远程调试的方法,请参考http://blog.sina.com.cn/s/blog_a459dcf5010153o7.html),然是当程序在用户手中出现崩溃此时我们可以采用Remote Debugg

Windbg 分析 dump

问题描述 用Windbg分析dump文件,查看是否有Memeryleaks.该从哪方面入手,怎样才算是Memeryleaks.我刚看这方面内容,只是知道些命令,希望大神能给予建议.谢了-- 解决方案 解决方案二:木有人回--也是毕竟今天是个特殊的日子,我还在这么苦逼的敲代码解决方案三:该回复于2014-08-02 23:55:03被版主删除解决方案四:不要沉底呀--

使用Eclipse Memory Analyzer进行堆转储文件分析

简介: Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个组成项目中之一,它是一个功能丰富的 JAVA 堆 转储文件分析工具,可以帮助你发现内存漏洞和减少内存消耗.本文主要介绍如 何安装配置 Memory Analyzer,并结合一个实例,介绍如何利用 MAT 来进行堆转 储文件分析,找到内存泄露的根源. 概述 对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我 们在测试阶段进行了大量卓有成

如何使用crash工具分析Linux内核崩溃转储文件

本文首先介绍了 crash 的基本概念和安装方法,其次详细介绍了如何使用 crash 工具分析内核崩溃转储文件,包括各种常用调试命令的使用方法,最后以几个实际工作中遇到的真实案例向读者展示了 crash 的强大功能.在这篇文章中,既有详细的工具使用方法,又有丰富的实际http://www.aliyun.com/zixun/aggregation/7734.html">案例分析,相信您读过以后定会受益匪浅. 什么是 crash 如前文所述,当 linux 系统内核发生崩溃的时候,可以通过 k

Windbg 分析Windows蓝屏原因的方法

蓝屏是系统崩溃.操作系统在遇到致命错误导致崩溃时,并不是直接挂掉,而是会记录下当时内存中的数据,将其存储成为dump文件,并用一串蓝屏代码向用户做出提示. 一.如何获取DUMP文件 右键点击"我的电脑",选"属性→高级→启动和故障恢复→设置",打开"启动和故障恢复"选项卡,在"写入调试信息"下拉列表中选中"小内存转储(64KB)"选项,如下图: 选好后点确定,下次再出现蓝屏时,系统就会存储下dump文件,一

蓝屏dump分析教程 使用WinDbg分析工具

  一.WinDbg是什么?它能做什么? WinDbg是在windows平台下,强大的用户态和内核态调试工具.它能够通过dmp文件轻松的定位到问题根源,可用于分析蓝屏.程序崩溃(IE崩溃)原因,是我们日常工作中必不可少的一个有力工具,学会使用它,将有效提升我们的问题解决效率和准确率. 三.设置符号表: 符号表是WinDbg关键的"数据库",如果没有它,WinDbg基本上就是个废物,无法分析出更多问题原因.所以使用WinDbg设置符号表,是必须要走的一步. 1.运行WinDbg软件,然后

用gdb配合内核转储文件瞬间定位段错误

前几天在写一个使用Huffman算法的文本压缩程序时被"段错误"折磨了好长时间.因为自己向来对内存的使用保持着"克勤克俭"的作风,所以总是被此类错误折磨的焦头难额.C语言的内存管理本来就是一个繁琐的工作,写代码时略有不慎便会出现诸如"段错误(吐核)"的运行时崩溃. 其实段错误是操作系统的一个内存保护机制,一般情况下某程序尝试访问其许可范围之外的内存空间时便会触发内核的"一般保护性异常",内核便会向程序发送一个SIGSEGV(1

怎么获得JVM的堆转储文件?

问题描述 我遇到一问题,就是在Eclipse上运行程序内存泄露了,使用的是自己安装的JVM(不是Eclipse自带的). 我现在正采用Eclipse Memory Analyzer 来分析内存泄露的原因,但是在分析前,必须要得到内存泄露一瞬间的堆转储文件. 现在问题是: 1. 怎么获得堆转储文件? 2.生成的文件在哪个目录? 3. 怎么设置JVM的参数,在哪里设置? 4.一个发生内存泄露时,JVM会保存堆转储文件吗?如果保存,会在哪个目录下呢? 问题补充:引用 解决方案 eclipse -> r

indows+蓝屏-Windows系统蓝屏,下面是bluescreanView和Windbg分析的结果,求高手帮忙看下~~谢谢

问题描述 Windows系统蓝屏,下面是bluescreanView和Windbg分析的结果,求高手帮忙看下~~谢谢 BlueScream分析结果: ==================================================** Dump File : 121814-18735-01.dmp Crash Time : 2014/12/18 7:19:00 Bug Check String : CRITICAL_OBJECT_TERMINATION Bug Check C