在 Visual Studio 2008 中为 .Net 托管应用程序从 WinDbg 调试 .dmp 文件
Posted
技术标签:
【中文标题】在 Visual Studio 2008 中为 .Net 托管应用程序从 WinDbg 调试 .dmp 文件【英文标题】:Debugging .dmp files from WinDbg in Visual Studio 2008 for .Net managed apps 【发布时间】:2010-11-15 10:34:00 【问题描述】:我正在尝试查找如何获取 .Net 托管可执行文件的故障转储,然后在 Visual Studio 2008 中打开生成的 .dmp 文件。我想查看在源代码中引发异常的位置,调用堆栈以及栈上函数中变量的值。
为了简化问题,我写了一个会崩溃的小应用:
...
class Program
static void Main(string[] args)
int a = 2; //Variable I want to see value for when debugging
if (!File.Exists(@"C:\Crasher\bin\Debug\file.txt")) //Doesn't exist
throw new FileNotFoundException(); //Unhandled exception thrown
...
我做了一个 DEBUG 构建并从 Visual Studio 外部运行它。在 windbg 中,我单击“附加到进程”并选择了我的应用程序。然后我在windbg命令窗口中输入:
.dump /ma C:\crasher\bin\debug\dump.dmp
然后我在 Visual Studio 中打开了 .dmp 文件。我去了工具->选项->调试->符号并添加了以下内容:
http://msdl.microsoft.com/download/symbols (saved to local folder)
这为我提供了模块窗口中列出的所有 DLL 的符号(例如 Kernel32.dll、gdi32.dll - 我认为所有列出的都是本机的),但 mscorlib.ni.dll 除外。 Microsoft Symbol Server 为我提供了 mscorlib.dll 但不是 mscorlib.ni.dll 的符号构建和 .pdb。
当我尝试为我的 .exe 本身加载 .pdb 时,它告诉我它与应用程序不匹配。我认为这是因为 .exe 是托管的,并且我们还没有它下面的所有本机代码的符号 - 即,如果我可以获得 mscorlib.ni.dll 的符号构建和 pdb,这将起作用。
这个推理正确吗?我还缺少其他东西吗?
无论哪种方式,为什么 mscorlib.ni.dll 在 Microsoft 符号服务器上不可用,我在哪里可以获得符号信息,还有什么我应该知道的通过 Visual Studio 中的故障转储调试托管代码。
非常感谢 - 任何帮助将不胜感激。
菲尔·惠廷顿
【问题讨论】:
不是JIT编译代码的dmp吗?这行得通吗? 我认为这是不可能的。 为什么还要使用 Visual Studio? WinDBG 要强大得多。 在 VS2008 中无法做到这一点。使用 VS 2010(我认为是终极版)你当然可以做到这一点。你最好的选择是使用 WinDbg。查看blogs.msdn.com/b/tess/archive/2006/05/18/… 这并不容易,但如果你能习惯使用 WinDbg,那么你的武器库中就会拥有一个非常强大的工具。 【参考方案1】:正如 Jason Evans 在他的评论中所说,这在 VS2008 中不受支持,但您可以在 WinDbg 中做到这一点。
为此类崩溃获取正确转储的最简单方法是使用 adplus(包含在 Windows 调试工具中)。有多种选择,但要根据进程名称获取故障转储,您可以这样做
>adplus -crash -o c:\dumpdirectory -pn app.exe
这会给你两个转储。一个用于第一次机会例外,一个用于第二次。在这种情况下,它们实际上是相同的,但对于更实际的情况,第一次机会异常转储将向您显示异常被抛出时(即在任何异常处理发生之前)的应用程序状态。第二次机会异常转储将向您显示未处理异常的状态。
要获取异常,请打开故障转储并通过键入 .loadby sos mscorwks
加载 SOS。
然后使用!pe
命令在当前线程上打印异常(在这种情况下将是故障线程)。它看起来像这样:
0:000> !pe
Exception object: 024a5114
Exception type: System.IO.FileNotFoundException
Message: Unable to find the specified file.
InnerException: <none>
StackTrace (generated):
SP IP Function
0020F0F0 005100D6 TestBench!TestBench.Program.Main()+0x66
StackTraceString: <none>
HResult: 80070002
要列出局部变量a
,请使用!clrstack -l
,但请记住,由于优化,局部变量很少在发布模式构建中可用。
0:000> !clrstack -l
OS Thread Id: 0x1a50 (0)
ESP EIP
0020f04c 7571b727 [HelperMethodFrame: 0020f04c]
0020f0f0 005100d6 TestBench.Program.Main()
LOCALS:
0x0020f0fc = 0x00000002 <--- the value of a
0x0020f0f8 = 0x00000000
0020f328 51141b5c [GCFrame: 0020f328]
【讨论】:
Brian,非常感谢你 - 我还没有尝试过,但想回复一下。如果有任何其他查询出现,将进一步发布:) 再次感谢。私服 @Phil 不客气。请务必查看带有 WinDbg/SOS 标记的问题,因为如果您要学习 WinDbg,其中一些可能会有所帮助。以上是关于在 Visual Studio 2008 中为 .Net 托管应用程序从 WinDbg 调试 .dmp 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Visual Studio 2008 中打开使用 Visual Studio 2005 创建的 rdl?
如何在 Visual Studio 2008 或 Visual Studio 2010 中设置 JavaScript 断点
我可以在 Visual Studio 2008 中使用 Visual Studio 6 编译的 C++ 静态库吗?
Visual Studio 2010 显示旧的 Visual Studio 2008“添加引用”对话框