为什么minidumps有时只有调用堆栈,对于同一个进程?

时间:2016-09-22 12:07:11

标签: .net callstack minidump

最近我们在生产中陷入困境。我使用ProcessExplorer来调试它,在cdb中保存了一个minidump并在VS2015中进行了分析。我可以使用代码中的符号在主线程上看到clr调用堆栈。

想要学习更多东西我创建了一个简单的程序,它会挂起(带有一点调用堆栈),如下所示(内置在Release中,在构建后移动了源代码):

public class Program
{
    public static void Main(string[] args)
    {
        new Program().Run();
    }

    public void Run()
    {
        DoThing();
    }

    public void DoThing()
    {
        Task t = new Task(() =>
            {
                while (true)
                {
                }
            }
        );

        t.RunSynchronously();
    }
}

我随后以三种方式创建了转储文件:

  1. 通过任务管理器
  2. 附加cdb和.dump / ma
  3. 附加到VS2015,破坏和保存转储文件
  4. 所有转储的大小都非常相似。当我在新的VS2015会话中打开它们时,只有最后一个方法显示主线程的clr调用堆栈。为什么是这样?我在VS中保存转储时没有看到调用堆栈,但是当我重新打开转储文件时,我会这样做。

    我如何保证在生产中创建转储时(当VS不可用时)可以看到clr调用堆栈。 当我第一次使用ProcessExplorer和cdb在生产中创建转储文件时,为什么我会得到一个clr调用堆栈?

    更新
    我已经检查了转储文件中的字符串,它们都包含如下值:
        < DoThing> b__2_0
        DoThing
        DoThing> b__2_0

    我的问题是由任务管理器或cdb创建的minidump具有主线程堆栈,例如:

    ntdll.dll!778214d1()
    [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
    mscorlib.ni.dll!7279bbc0() 
    

    而visual studio创建的主要线程堆栈如下:

    DumpDiag.exe!DumpDiag.Program.DoThing.AnonymousMethod__2_0()
    mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke()
    mscorlib.dll!System.Threading.Tasks.Task.Execute()
    

1 个答案:

答案 0 :(得分:0)

原来这是因为我的.net进程是32位,但我用cdb和任务管理器捕获的minidump是64位。我错误地使用x64版本的cdb,以及(默认)64位任务管理器捕获64位转储。

我在上面创建了单独的32位和64位版本的测试过程,并使用相关版本的cdb,相关版本的任务管理器以及附加Visual Studio捕获了小型转储。在此之后,所有转储都正确显示了clr调用堆栈。

更多信息:https://blogs.msdn.microsoft.com/tess/2010/09/29/capturing-memory-dumps-for-32-bit-processes-on-an-x64-machine/