2008-11-26 11 views
9

Estoy intentando generar algún código en tiempo de ejecución utilizando la clase DynamicMethod en el espacio de nombres Reflection.Emit pero por alguna razón está lanzando una "VerificationException". Aquí está el código IL que estoy tratando de usar ...Cómo depurar el código IL generado en tiempo de ejecución utilizando Reflection.Emit

ldarg.1 
ldarg.0 
ldfld, System.String FirstName 
callvirt, Void Write(System.String) 
ldarg.1 
ldarg.0 
ldfld, System.String LastName 
callvirt, Void Write(System.String) 
ldarg.1 
ldarg.0 
ldfld, Int32 Age 
callvirt, Void Write(Int32) 
ret 

Necesito una forma de depurar el código IL generado. ¿Que opciones tengo? Estoy usando el profesional VS2008.

Respuesta

2

Pruebe usar la herramienta peverify para verificar la IL. De MSDN:

peverify.exe realiza controles exhaustivos verificación MSIL basado en el análisis de flujo de datos más una lista de varios cientos de normas sobre metadatos válidos . Para obtener información detallada sobre los controles Peverify.exe realiza, ver los "metadatos de validación Especificación" y el "MSIL Especificación del conjunto de instrucciones" en el Herramientas Guía de desarrolladores de carpeta en el .NET Framework SDK.

No obstante, deberá guardar el código generado en el disco como un ensamblaje para que esto sea útil.

0

No hay manera de depurar IL directamente en el sentido de usar un depurador (no incorporado al menos). En realidad, solo tiene dos opciones aquí

  1. Ask Rob suggested. Escriba manualmente IL y ilasm en una DLL/EXE. Luego ejecute peverify en la DLL resultante para ver su error.
  2. Si realmente quiere depurar el IL, entonces probablemente se quede con el ensamblaje sin procesar.
0

Necesita emitir información simbólica para poder depurar la IL.

Emitting Symbolic Information with Reflection Emit

y coinciden con los códigos de operación emitidos con la ubicación coresponding en su expediente que lo emite. (Donde ILGenerator.Emit() es llamada).

Pero esto ciertamente no es una tarea trivial.

Editar:

no se puede depurar el código que no es verificable, que no consigue Jit-ed en absoluto. Debe verificar el uso correcto de IL ops. ¿cada uno de ellos tiene en la pila los operandos apropiados del tipo requerido que espera?

Edición 2:

y la manera fácil de hacerlo es crear el código en C# y luego utilizar Reflector o algún otro desensamblador IL también ver la IL y compararlo con el suyo.

Editar 3: Lamentablemente, la información de depuración no se puede emitir utilizando DynamicMethod, pero WinDBG se puede utilizar para volcar el IL, José Fco Bonnin lo explica en su blog.Executing dynamic IL with DynamicMethod:

El principal problema que experimentamos con DynamicMethod es que no tenemos la capacidad de generar información de depuración para LCG, ya que la API de depuración es basado en metadatos que la LCG no no tiene. En cualquier caso, no todo se pierde ya que podemos continuar depurando con WinDBG. ...

el proceso se explica con más detalle en la publicación.

+0

¿Puedo utilizar la información simbólica con métodos dinámicos (LCG)? He comprobado mi IL contra el reflector y son idénticos. Pero no estoy seguro de si el IL generado es en realidad ** idéntico. –

+0

He hecho una edición para responder a su pregunta, espero que ayude. –

0

Esto puede no ayudarlo en el fin de la depuración, pero RunSharp es una buena herramienta para generar IL que le ayuda a evitar errores comunes. Hace que escribir IL se parezca mucho más a escribir C#.

He aquí un resumen de ejemplos: http://www.codeproject.com/KB/dotnet/runsharp.aspx

+0

He intentado con RunSharp y debo decir que quedé impresionado, pero finalmente me decidí a hacerlo de la manera más difícil, ya que parece haber sido abandonado. Por ejemplo, no puede verificar el valor de retorno de una llamada a un método (Invoke no tiene mecanismo para devolver el valor devuelto). –

0
ldarg.1 
ldarg.0 
ldfld, System.String FirstName 
callvirt, Void Write(System.String) 

En esta etapa todavía tiene arg1 en la pila.

+1

Sí, que se usa como argumento para la llamada a BinaryWriter :: Write. Es una referencia a un objeto BinaryWriter y se pasa como "este puntero". –

+0

Derecha :) ¡Perdí eso! – leppie

Cuestiones relacionadas