从使用WinDbg的转储确定的InnerException的行数(Determine line nu

2019-09-23 08:46发布

我试图追查从转储一个NullReferenceException。 该NullReferenceException异常是不是崩溃的异常,而崩溃的例外是包含一个InnerException这是一个NullReferenceException异常TargetInvocationException。

我使用WinDBG的与SOS,我用命令analyze -v ,这给我的NullReferenceException的调用堆栈:

EXCEPTION_OBJECT: !pe f6cb150
Exception object: 000000000f6cb150
Exception type:   System.NullReferenceException
Message:          Object reference not set to an instance of an object.
InnerException:   <none>
StackTrace (generated):
SP               IP               Function
000000002CD9D8C0 000007FF01E7C639 MyDll!DoSomething2()+0xe99
000000002CD9DBE0 000007FF01E7B11D MyDll!DoSomething1()+0x43d
000000002CD9DD20 000007FF01E7AB11 MyDll!WorkerDoWork(System.Object, System.ComponentModel.DoWorkEventArgs)+0x51
000000002CD9DD80 000007FEEA68A0F2 System_ni!System.ComponentModel.BackgroundWorker.WorkerThreadStart(System.Object)+0x62

请注意,我得到与字节偏移方法名,但没有行号。 DoSomething2是一个大的功能,所以NullReferenceException异常发生的位置不是很明显。

我试图按照苔丝Ferrandez的博客的说明:

.NET异常-追查在代码中发生的异常

但我得到了早期,我试图确定该方法的方法描述卡住DoSomething2使用ip2md用了doSomething2的IP:7FF01E7C639:

> !ip2md 7FF01E7C639
Failed to request MethodData, not in JIT code range

注意!ip2md命令在TargetInvocationException发生地法的IP成功。

问题

我在哪里可以从这里去缩小东西线了doSomething2崩溃? 需要注意的是,我不能重现崩溃,所以我只有这一点(和几个副本)转储。

其他注意事项

  • .NET 4.0
  • WinDbg的版本:6.12.0002.633 AMD64
  • 我是新来WinDBG的:让更多的信息,更好的

编辑1

当我没有设置正确的符号,我得到如下:

STACK_TEXT:  
00000000`2cd9d8c0 00000000`ffffffff MyDll!Unknown_0xe99+0xe99
00000000`2cd9dbe0 00000000`ffffffff MyDll!Unknown_0x43d+0x43d
00000000`2cd9dd20 00000000`ffffffff MyDll!Unknown_0x51+0x51
00000000`2cd9dd80 00000000`ffffffff system_ni!    System.ComponentModel.BackgroundWorker.WorkerThreadStart+0x62

!当我将它设置为指向我的符号服务器,并打开SYM嘈杂的,它似乎正确加载符号:

0:000> ld MyDll
DBGHELP: C:\Program Files\Debugging Tools for Windows (x64)\MyDll.dll - file not found
SYMSRV:  c:\symbols\MyDll.dll\4F3D6F4B154000\MyDll.dll not found
SYMSRV:  http://msdl.microsoft.com/download/symbols/MyDll.dll/4F3D6F4B154000/MyDll.dll not found
SYMSRV:  \\mysymbolserver\store\Mydll.dll\4F3D6F4B154000\file.ptr
SYMSRV:  MyDll.dl_ from \\mysymbolserver\store: uncompressed
DBGHELP: c:\symbols\MyDll.dll\4F3D6F4B154000\MyDll.dll - OK
DBGENG:  c:\symbols\MyDll.dll\4F3D6F4B154000\MyDll.dll - Mapped image memory
SYMSRV:  c:\symbols\MyDll.pdb\8AFC2BE7529A41289FA9FBCEDB6836161\Mydll.pdb not found
SYMSRV:  http://msdl.microsoft.com/download/symbols/Mydll.pdb/8AFC2BE7529A41289FA9FBCEDB6836161/MyDll.pdb not found
SYMSRV:  \\mysymbolserver\store\MyDll.pdb\8AFC2BE7529A41289FA9FBCEDB6836161\file.ptr
SYMSRV:  MyDll.pd_ from \\mysymbolserver\store: uncompressed
DBGHELP: MyDll - private symbols & lines 
     c:\symbols\MyDll.pdb\8AFC2BE7529A41289FA9FBCEDB6836161\MyDll.pdb
Symbols loaded for MyDll

编辑2

我试着用name2ee如下!

0:000> !name2ee MyDll!MyType.DoSomething2
Module:      000007ff004995b8
Assembly:    Autodesk.DataManagement.Client.Framework.Vault.dll
<invalid module token>

所以,没有运气。 但后来我几乎似乎与此得到的地方:

0:000> !name2ee MyDll.dll!MyNamespace.MyType
Module:      000007ff004995b8
Assembly:    MyDll.dll
Token:       000000000200008c
MethodTable: 000007ff01b2e258
EEClass:     000007ff01b415e0
Name:        MyNamespace.MyType

0:000> !dumpmt -md 7ff01b2e258
EEClass:      000007ff01b415e0
Module:       000007ff004995b8
Name:         MyNamspace.MyType
mdToken:      000000000200008c
File:         C:\Program Files\MyCompany\MyProduct\Bin\MyDll.dll
BaseSize:        0x30
ComponentSize:   0x0
Slots in VTable: 31
Number of IFaces in IFaceMap: 2
--------------------------------------
MethodDesc Table
           Entry       MethodDesc      JIT Name
000007feeb31a2c0 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007feeb3689f0 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007feeb3688c0 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007feeb353440 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01b01300 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01e89140 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01b9c080 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01f45f40 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01a9b358 000007ff01b2e128     NONE MyType.DoSomething3()
000007ff01a9b360 000007ff01b2e130     NONE MyType.DoSomething4()
000007ff01a9b368 000007ff01b2e138     NONE MyType.DoSomething5()
000007ff01e79800 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff020fea80 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01a9b3b0 000007ff01b2e1b0     NONE MyType.DoSomething6()
000007ff01a9b3b8 000007ff01b2e1b8     NONE MyType.DoSomething7()
000007ff01a9b328 000007ff01b2e0f0     NONE MyType..ctor()
000007ff01b01280 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01e7a810 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01e7aac0 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01e83240 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01f19520 000007ff01b2e178      JIT MyType.RunWorkerCompleted(System.Object, System.ComponentModel.RunWorkerCompletedEventArgs)
000007ff01e7ace0 0000000000000000      JIT 0000000000000000 is not a MethodDesc
000007ff01e7b7a0 0000000000000000      JIT 0000000000000000 is not a MethodDesc
000007ff01e7b710 0000000000000000      JIT 0000000000000000 is not a MethodDesc
000007ff01e7d2b0 0000000000000000      JIT 0000000000000000 is not a MethodDesc
000007ff01b015f0 0000000000000000      JIT 0000000000000000 is not a MethodDesc
000007ff01b88ce0 0000000000000000      JIT 0000000000000000 is not a MethodDesc
000007ff01a9b3e0 000007ff01b2e200     NONE MyType.DoSomething8()
000007ff01b921e0 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01b933b0 0000000000000000     NONE 0000000000000000 is not a MethodDesc
000007ff01b93870 0000000000000000     NONE 0000000000000000 is not a MethodDesc

我猜所有缺少的条目(那些上市“不是一个方法描述”)是由于这不是一个完整的小型转储。 那正确吗?

Answer 1:

在上述评论,您提的是,|| 命令产量“用户小型转储”。 为了正确调试.NET代码,你需要一个完整的转储,这表明“全内存用户小型转储”从|| 命令。 我觉得这是你的问题。 如果没有获得充分装载机堆,它不可能映射一个代码地址回.NET方法,所以你不能得到一个堆栈跟踪。 如果你能重现此问题,获取完全转储。 您可以使用ADPlus,ProcDump或DebugDiag资料捕获转储上崩溃。



Answer 2:

它看起来像的WinDbg不拿起你的DLL符号。 您可以考虑通过设置符号路径和使用!sym noisy必要时排除故障。

我不能说为什么!ip2md不会在这种情况下工作,但也有其他方式来获得的代码DoSomething2 。 试试!name2ee方法名,如!name2ee *!TypeName.DoSomething2或者您也可以通过这样的类型本身得到它!name2ee *!Namespace.TypeName然后!dumpmt -md <method table>对你的方法表从!name2ee

一旦你的代码中, !u命令可以显示你的汇编代码的.NET注释转储。 通过使用从异常的偏移量,你可能能够确定的NullReferenceException的性质。



Answer 3:

您可能正在使用一个精简PDB文件,在发布版本的一个项目生成的默认。 所有的文件和行号信息是从这样的文件中删除。

切换到发布配置,项目+属性,构建选项卡,高级,调试信息=“满”。

这是故意顺便说一句,行号信息不是发布版本非常准确。 抖动优化四处移动代码,所以你需要记住,所显示的行数为近似值。



文章来源: Determine line number of InnerException from minidump using WinDbg