I am using Windbg to load a crash dump from managed code (C#, a console application built for Any CPU), and crash dump is created on x64 platform. I am debugging on x64 platform.
I have using the following command to load private symbol of my application. Here are what the commands I am using in Windbg.
(set symbol path and copy FooService.pdb pdb file to local symbol path D:\Debug)
0:016> .reload /f
.*** WARNING: Unable to verify checksum for FooService.exe
DBGHELP: FooService.pdb- private symbols & lines
D:\Debug\FooService.pdb
0:016> lm
start end module name
00000000`00400000 00000000`0041c000 FooService C (private pdb symbols) D:\Debug\FooService.pdb
My confusion is, when using the following command, no line number information is showed in stack trace. Any ideas what is wrong? Do I need to set source path?
0:016> ~6 e!clrstack
EDIT 1: I met with some issues with using !pe and !U to find stack trace where the exception is thrown.
Here is my debug process. At first I use !pe to print stack trace for the exception object, when I use !U to diassemble the code. The issue I find is !U will diassemble all function code of FooService.ProcessOrders(), and I want to find the exact place where in function FooService.ProcessOrders the crash happens. I also find the diassembled annotated IL code only contains function calls I made (for non-function call C# code, for example a=a*2, only assembly language is shown), not exactly IL mapped to each line of C# code, (1) is that the correct expected behavior? (2) what is the solution or further suggestion to find the exact failed C# code from my analysis posted here?
!pe 0000064280155325
StackTrace (generated):
SP IP Function
000000001A56DA70 00000642B74E3B7A System.Data.SqlClient.SqlCommand.InternalExecut开发者_开发知识库eNonQuery(System.Data.Common.DbAsyncResult, System.String, Boolean)
000000001A56DB10 00000642B74E3FCC System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
000000001A56DB90 0000064280155325 FooService.ProcessOrders()
000000001A56F3E0 0000064280153A21 FooService.RountineJob()
!U 0000064280155325
thank in advance, George
WinDbg/SOS doesn't map line numbers to the output of !clrstack
. So as long as lm
tells you that you have private pdb symbols for your own assemblies you setup is correct. Unfortuntately the current versions of WinDbg/SOS doesn't support source level debugging to the same extend as for native code.
EDIT: Regarding exceptions. When you do a !pe
, it will tell you the call stack as well as offsets into the relevant methods. If you take the address from the IP column of the !pe
output and do a !U
on that, you will see the JITTED code for the relevant method. The IP column will be the last address of the code that generated the exception (so you have to do a little counting to find the correct instruction).
The disassembled output is annotated with .NET calls so it is no hard to map this against the IL or source code. That should help you identify exactly which throw statement you're looking for.
That being said, you will make debugging a lot easier if you split methods into a number of smaller methods. If you do that, the method name is usually enough to pinpoint the location of the exception. I realize that is not always an option, but it is worth considering.
精彩评论