Windows Phone App的dump文件实例分析-Stack Overflow

前言

这篇文章我们一起来分析一个从Windows Phone Dev Center上下载下来的dump file。首先按照我上一篇的步骤设置好我们的Windbg,并按住Ctrl +D打开dumpfile。可以看到下面的界面:

分析一个dump file可以分解为4个步骤,第一步是信息收集,第二步是定位异常上下文,第三步分析和推理出现问题的原因,第四步分析和定位我们的源代码并进行修复和验证。

信息收集

我们可以使用一些命令浏览一下这个dump file对应的系统版本和一些模块的信息辅助我们后面的分析。

1. version命令,查看系统版本号

2. lm命令,显示当前加载的模块。

可以使用lmv命令查看所有模块的详细信息,如果想看某一模块的详细信息,需要使用参数m,比如查看System_Data_Linq_ni.dll的详细信息,”lmv mSystem_Data_Linq_ni”

定位异常上下文

当异常发生的时候,寄存器的上下文会被异常分发器保存在栈上。我们可以通过一些方法找到并恢复发生异常时候的上下文,从上下文中找到我们需要的信息,这里使用”!analyze -v”命令。

1. 首先确认发生异常的线程。有时候发生异常的线程不止一个,我们在使用 “!analyze –v”之前需要确认发生异常的线程。使用”~* kvb”命令来查看所有线程的调用堆栈。”~*“ 命令是枚举所有的线程,”kvb“命令是列出线程的调用堆栈。

可以发现所有的线程都是等待状态,只有线程0不是,从线程0的callstack可以看出来线程0就是我们要找的发生异常的那个线程,。

2. 切换到发生异常的线程,”~0 s”

3. 使用“!analyze –v”,这个扩展命令来帮助我们找到发生异常时候的上下文,并显示当时的调用堆栈,有些情况下给出的调用堆栈并不是发生异常的第一现场,遇到这种情况我们需要进一步分析。

分析和推测

在上面的显示中,我们发现一个很有意思的托管调用堆栈,里面反复出现了”System.Diagnostics.StackTrace..ctor()+0x12”。看起来StackTrack这个类型的对象在构造的时候调用了自己的成员函数GetStackFramesInternal,而这个函数又去构造了新的StackTrack的对象,如此反复以至于发生了循环调用而导致栈被耗尽,这里并没有给出与我们的代码相关的调用,看起来很像一个.net framework的bug。那么为什么会发生这样的调用呢?让我们继续进行分析,看看是哪里引发了这个调用。

为了找到更多的线索,我们可以进一步查看发生异常的线程栈里都保留了什么,我们可以通过”!teb”命令来查看当前线程的属性,并找到栈的基址和大小,有了栈的基址和大小,我们就可以查看里面的内容了。

1. 查看当前线程的属性,”!teb”命令

2. ”dps + 地址范围”命令可以让我们查看栈里面保留的信息。

跳过这些无效的内容,我们继续往后查看。

红线的模块和函数正是我们App中的代码,我们可以做一个大胆的推理在这里。我们的函数DecrementPendingAndFinishIfNecessary调用了Logger.Info函数,这个函数使用了系统的StackTrace.CaptureStackTrace来获取当前的调用堆栈。那么为什么这个函数StackTrace.CaptureStackTrace又会去构造它自己的对象呢?让我们打开我们程序的源代码进一步分析。

分析和定位我们的源代码

打开我们的代码并找到Logger.Info的实现,红色的代码正是验证了我们上面的推理。在一些极端的形况下,StackTrace会创建失败并扔出异常,这个异常恰好被后面的catch块捕获再次调用了Logger的函数,而这个函数会再次创建StackTrace类型的对象,继续触发异常导致了反复的调用。

private static void WriteLine(Level level, string message)
{
    try
    {
        if (0 == message.Length)
        {
            return;
        }
        StackTrace st = new StackTrace(); // 1. 这里exception
        string name = st.GetFrame(2).GetMethod().Name;
        string prefix = string.Format("[{0}]@{1}", level, name);
        message = prefix + "-" + message;
    }
    catch (Exception e)
    {
        Logger.Fatal("Faild in WriteLog,message:" + e.Message); // 2. 然后执行这里
    }
}

public static void Fatal(string message)
{
    WriteLine(Level.Fatal, message); //3. 这里继续执行1, 1 继续exception
}

知道了原因,我们就可以修改代码来修复了,最简单的方法就是先去掉catch里面的调用。

后续问题

那么为什么系统的StackTrack的GetStackFramesInternal会失败呢?感兴趣的同学可以尝试反编译命令来查看里面的细节。

分享代码,改变世界!

时间: 2024-10-05 04:40:25

Windows Phone App的dump文件实例分析-Stack Overflow的相关文章

Windows Phone App的dump文件实例分析- System.ExecutionEngineException

前言 在开始这篇文章之前我们先来讲讲如何从高度优化的Release版的Dump中找到正确的异常上下文地址,并手动恢复异常发生的第一现场. 1. 什么是异常上下文 简单来说,在windows体系的操作系统里面,每个线程都有自己的线程上下文来保存需要的信息,其中包括当前寄存器的值.我们这里需要找到的异常上下文就是当异常发生的时候,异常分发器帮我们保存的当前寄存器的值(也叫寄存器上下文),利用这些信息结合汇编代码的分析,我们就可以进一步找到发生异常的原因.关于寄存器上下文结构体的定义我们可以在winn

Windows Phone App的dump 文件分析

前言 我们在发布了自己的App以后,Windows Phone的Error Report机制会帮助我们收集程序的崩溃信息并发送到微软的服务器上,这可以辅助开发者提高App的稳定性. 那么如何利用这些dump file呢?首先我们需要下载这些dump file从微软开发者网站,然后借助调试工具进行分析,我们这里选用Windbg. 下载步骤 1. 登录http://dev.windows.com/en-us/dashboard 2. 选择Windows Phone Store 3. 进入Report

HTTP的上传文件实例分析

HTTP的上传文件实例分析 由于论坛不支持Word写文章发帖. 首先就是附件发送怎么搞,这个必须解决.论坛是php的.我用Chrome类浏览器跟踪请求,但是上传的文件流怎么发过去没找到,估计流可能多或者什么的不好显示,只知道发送了文件名字.需要实际了解下post文件,不能只会后台或界面不了解前台数据处理和协议怎么传送数据. 图中:有些相关文章 HTTP请求中的form data和request payload的区别 AJAX POST请求中参数以form data和request payload

ADPLUS使用配置文件设置断点时无法创建DUMP文件原因分析

ADPLUS简介 ADPLUS.vbs是Debugging Tool for Windows里带的一个VBS脚本.我们可以用它很方便地生成进程的内存转储文件.从Debugging Tool for Windows版本6.12.2.633后,ADPLUS.vbs被ADPLUS.EXE所替代.原有的VBS脚本更名为adplus_old.vbs. 背景 在一台服务器上,ASP.NET出现随机崩溃的情况.为了解决这个问题,我们决定用ADPLUS收集dump. 我们使用如下配置文件: <ADPlus Ve

[JAVA]JAVA章3 如何获取及查看DUMP文件

一.dump基本概念 在故障定位(尤其是out of memory)和性能分析的时候,经常会用到一些文件来帮助我们排除代码问题.这些文件记录了JVM运行期间的内存占用.线程执行等情况,这就是我们常说的dump文件.常用的有heap dump和thread dump(也叫javacore,或java dump).我们可以这么理解:heap dump记录内存信息的,thread dump是记录CPU信息的. heap dump: heap dump文件是一个二进制文件,它保存了某一时刻JVM堆中对象

dump文件解析之探索.Net的内存

前言: 对于需要长时间运行的.net程序,有时需要我们查看内存的使用有没有内存泄露问题. 我们可以从dump文件中找到答案. Dump的看点 用dump文件来分析内存,到底我们需要关心哪些点呢? 内存的使用情况 HeapSize/object的数量 也就是托管堆使用大小以及托管堆内有多少数量的对象 1.1  查看有没有存在有占用大量内存的对象 <比如有某类下面的一个集合>  1.2  0 1 2各代的size<查看各代的内存是否有异常> 2.调查是否有内存泄露(重点) 2.1  查

使用jprofiler分析dump文件一个实例

1.. jstact 命令先分析一下 一次fullgc之后 old 老年代使用比例 只降低2% 应该有什么大的对象常驻内存. 2.可以使用jmap 命令查看对象大小 (这里后面使用jprofiler 就没用这个命令) jmap -histo:live 72947 | more 3 .dump 线上文件栈 [[email protected] ~]# jmap -dump:live,format=b,file=heap201712.hropf  72947   Dumping heap to /r

.NET对象与Windows句柄(三):句柄泄露实例分析

在上篇文章.NET对象与Windows句柄(二):句柄分类和.NET句柄泄露的例子中,我们有一个句柄泄露的例子.例子中多次创建和Dispose了DataReceiver和DataAnalyzer对象,但由于忘记调用DataAnalyzer的Stop方法,导致产生句柄泄露.本文假定我们已经发现了泄露现象但还不知道原因,讨论如何在这种情况下分析问题. 一.发现问题 在程序运行约一个小时以后,通过任务管理器发现句柄数超过5000,线程数也超过1000.对于一段只需要并行接收和分析数据的简易代码来说,这

蓝屏 Dump文件分析方法

WinDbg使用有点麻烦,还要符号表什么的.试了下,感觉显示很乱,分析的也不够全面... 试试其他的吧!今天电脑蓝屏了,就使用其dump文件测试,如下: 1.首先,最详细的,要属Osr Online这个在线分析网站了: 打开其分析地址:http://www.osronline.com/page.cfm?name=analyze 下拉,找到上传按钮(上图),将需要分析的dump文件浏览上传即可...dump文件一般在C:\www\minidump下 分析完成后生成的内容非常多: 主要看第一个Pri