最近我们在生产中陷入困境。我使用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();
}
}
我随后以三种方式创建了转储文件:
所有转储的大小都非常相似。当我在新的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()
答案 0 :(得分:0)
原来这是因为我的.net进程是32位,但我用cdb和任务管理器捕获的minidump是64位。我错误地使用x64版本的cdb,以及(默认)64位任务管理器捕获64位转储。
我在上面创建了单独的32位和64位版本的测试过程,并使用相关版本的cdb,相关版本的任务管理器以及附加Visual Studio捕获了小型转储。在此之后,所有转储都正确显示了clr调用堆栈。