已加载私有符号但未显示行号?
我正在使用 Windbg 从托管代码(C#,为任何 CPU 构建的控制台应用程序)加载故障转储,并且故障转储是在 x64 平台上创建的。我正在 x64 平台上进行调试。
我使用以下命令来加载应用程序的私有符号。以下是我在 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
我的困惑是,当使用以下命令时,堆栈跟踪中没有显示行号信息。任何想法有什么问题吗?需要设置源路径吗?
0:016> ~6 e!clrstack
编辑 1:我在使用 !pe 和 !U 查找引发异常的堆栈跟踪时遇到了一些问题。
这是我的调试过程。首先,当我使用 !U 反汇编代码时,我使用 !pe 打印异常对象的堆栈跟踪。我发现的问题是 !U 将反汇编 FooService.ProcessOrders() 的所有函数代码,并且我想找到函数 FooService.ProcessOrders 中发生崩溃的确切位置。我还发现反汇编的带注释的 IL 代码仅包含我所做的函数调用(对于非函数调用 C# 代码,例如 a=a*2,仅显示汇编语言),而不是精确映射到 C# 代码的每一行的 IL,( 1)这是正确的预期行为吗? (2) 从我在此处发布的分析中找到确切失败的 C# 代码的解决方案或进一步建议是什么?
!pe 0000064280155325
StackTrace (generated):
SP IP Function
000000001A56DA70 00000642B74E3B7A System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(System.Data.Common.DbAsyncResult, System.String, Boolean)
000000001A56DB10 00000642B74E3FCC System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
000000001A56DB90 0000064280155325 FooService.ProcessOrders()
000000001A56F3E0 0000064280153A21 FooService.RountineJob()
!U 0000064280155325
预先感谢, 乔治
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.InternalExecuteNonQuery(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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
WinDbg/SOS 不会将行号映射到
!clrstack
的输出。因此,只要 lm 告诉您您自己的程序集有私有 pdb 符号,您的设置就是正确的。不幸的是,当前版本的 WinDbg/SOS 不支持与本机代码相同程度的源代码级调试。编辑:关于例外情况。当您执行
!pe
时,它会告诉您调用堆栈以及相关方法的偏移量。如果您从!pe
输出的 IP 列中获取地址并对其执行!U
,您将看到相关方法的 JITTED 代码。 IP 列将是生成异常的代码的最后一个地址(因此您必须进行一些计数才能找到正确的指令)。反汇编的输出带有 .NET 调用注释,因此不难将其映射到 IL 或源代码。这应该可以帮助您准确识别您正在寻找的 throw 语句。
话虽这么说,如果将方法拆分为许多较小的方法,调试将会变得更加容易。如果这样做,方法名称通常足以查明异常的位置。我意识到这并不总是一个选择,但值得考虑。
WinDbg/SOS doesn't map line numbers to the output of
!clrstack
. So as long aslm
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.