2012-10-02 8 views
6

Estoy intentando rastrear una NullReferenceException desde un volcado. NullReferenceException no es la excepción que falla, sino que la excepción de bloqueo es una TargetInvocationException con una InnerException que es la NullReferenceException.Determine el número de línea de InnerException desde el minivolcado usando WinDbg

estoy usando WinDbg con SOS, yo uso el comando analyze -v y esto me da la pila de llamadas de la 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 

Aviso, que tengo los nombres de los métodos con los desplazamientos de bytes, pero sin Línea de números. DoSomething2 es una función grande, por lo que no es obvio dónde se produjo la excepción NullReferenceException.

he tratado de seguir las instrucciones en el blog de Tess Ferrandez:

.Net exceptions - Tracking down where in the code the exceptions occurred

Pero me quedé atrapado desde el principio en el que tratan de determinar el descriptor de método para el método DoSomething2 usando ip2md con el IP de DoSomething2! : 7FF01E7C639:

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

Tenga en cuenta que el comando ip2md tiene éxito en la IP del método donde se produjo el TargetInvocationException!.

Pregunta:

¿Dónde puedo ir desde aquí a reducir lo que la línea de DoSomething2 está fallando? Tenga en cuenta que no puedo reproducir el bloqueo, por lo que tengo todos estos volcados (y varios duplicados).

Notas adicionales:

  • .NET 4.0
  • WinDbg Versión: 6.12.0002.633 AMD64
  • Soy nuevo en WinDbg: así que cuanto más información, mejor

Editar 1

Cuando no me he símbolos configurado correctamente, me sale el siguiente:

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 

Cuando lo configuro para que apunte a mi servidor de símbolos y encienda SYM ruidoso, parece cargar símbolos correctamente:

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 

Editar 2

he intentado utilizar name2ee de la siguiente manera:!

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

Entonces, no hubo suerte allí.Pero entonces me parecía casi llegar a alguna parte con esto:

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 

Supongo todas las entradas que faltan (los indicados con "no es un MethodDesc") se deben a no ser un mini volcado completo. ¿Está bien?

+0

No necesita símbolos para obtener un seguimiento de pila administrada. Sin embargo, generalmente necesitas un botadero completo. ¿Es esto una descarga completa del proceso o simplemente un mini-volcado? –

+0

Sí, las entradas faltantes son causadas probablemente por el volcado no está lleno. –

Respuesta

3

En un comentario anterior, mencionas que || comando produce "mini volcado de usuario". Para depurar correctamente el código .NET, necesita un volcado completo, lo que indicaría un "volcado de usuario de memoria completa" desde el || mando. Creo que este es tu problema Sin acceso a los montones del cargador completo, no es posible asignar una dirección de código a un método .NET, por lo que no puede obtener un seguimiento de la pila. Si puede reproducir este problema, capture un volcado completo. Puede usar ADPlus, ProcDump o DebugDiag para capturar un volcado en caída.

4

Parece que WinDbg no recoge símbolos para su DLL. Puede ver eso estableciendo la ruta del símbolo y usando !sym noisy para solucionar los problemas según sea necesario. No puedo decir por qué !ip2md no funciona en este caso, pero hay otras maneras de obtener el código para DoSomething2. Pruebe !name2ee en el nombre del método, p. Ej. !name2ee *!TypeName.DoSomething2 o puede obtenerlo a través del tipo de este !name2ee *!Namespace.TypeName y luego !dumpmt -md <method table> en la tabla de métodos que obtiene de !name2ee.

Una vez que tenga el código, el comando !u puede mostrarle un volcado anotado en .NET del código ensamblador. Al utilizar el desplazamiento de la excepción, es posible que pueda determinar la naturaleza de la NullReferenceException.

+0

Gracias! Pensé que tenía símbolos cargados. Sin símbolos, obtengo resultados diferentes (ver mis ediciones en la pregunta). Probaré los métodos alternativos pronto e informaré. –

+0

La mayoría de los comandos de depuración de .NET no funcionarán si el volcado no es un volcado completo. Me pregunto si ese es el caso aquí? –

+0

@SteveJohnson, ¿hay alguna manera de decir si esto es o no un vertedero completo? el comando! ip2md funciona para que el descriptor de método de la funcione donde ocurrió la falla final. –

4

Probablemente esté utilizando un archivo PDB eliminado, el predeterminado generado para un proyecto en la compilación Release. Toda la información del número de archivo y línea se elimina de dicho archivo.

Cambie a la configuración de Release, Project + Properties, pestaña Build, Advanced, Debug Info = "full".

Esto es intencional por cierto, la información del número de línea no es muy precisa para la versión de lanzamiento. El optimizador de fluctuación de fase mueve el código, por lo que deberá tener en cuenta que un número de línea que se muestra es una aproximación.

Cuestiones relacionadas