2010-04-09 13 views
6

¡Estoy realmente perplejo por este!¿Cómo puedo recuperar el archivo fuente de un método compilado?

El objeto StackFrame (MSDN Link) tiene un método GetFileName que devuelve la ruta original del archivo fuente que compiló el método de ejecución (los símbolos proporcionados se generaron y se incluyeron con los ensamblajes en ejecución). Parece que esta información se usa para generar texto de excepción completo.

Estoy tratando de encontrar una manera de obtener esta información si el método no se está ejecutando actualmente. Estuve hurgando en la API de reflexión y no he visto una forma de obtener esta información. Supongo que debe estar allí en alguna parte.

¿Alguien más sabe de un método basado en la reflexión (o de hecho cualquier otro método) que pueda obtener el nombre del archivo de código?

Cualquier idea, comentario o abuso aceptado con gratitud.

¡Muchas gracias!

Respuesta

4

Reflection solo puede proporcionar información de tipo de los metadatos del conjunto. Obtener la dirección requiere el archivo de depuración .pdb y la dirección de la función en la memoria compilada por el compilador JIT. No puede obtener la dirección sin el método StackFrame.GetNativeOffset() o las interfaces del depurador, suponiendo que el método esté incluso compilado. El último enfoque no puede funcionar en proceso, un programa no puede depurarse solo.

El CLR no tiene ningún problema porque puede recuperar la dirección de método de los marcos de pila cuando procesa la excepción. Eso sigue siendo un arte imperfecto, no puede ver las direcciones de los métodos que estaban en línea. Tener esos marcos de pila es el primer paso requerido.

+0

Muchas gracias, tiene sentido. Ah bueno :) –

0

Utilice el descompilador RedGate Reflector para inspeccionar el conjunto que contiene la clase.

+0

Gracias por su respuesta. No sabía que Reflector pudiera hacer eso, eso es increíble, pero esto es algo que me gustaría poder hacer desde el código ya que encajará en un sistema existente. –

1

Puede leer la información del archivo .pdb y evaluarlo usted mismo. Contiene toda la información que necesita. No he terminado de leer el código, pero mi entendimiento es la siguiente:

  • Se obtiene el token de metadatos del método en cuestión a través de la reflexión
  • consultar los datos de AP para esa señal
  • La AP entrada contiene el nombre del archivo de origen y el número de línea

Un token de metadatos es un número de 32 bits que consta de un tipo de byte y un número de serie. Ese token describe cada entidad individual en un archivo de ensamblaje .NET: tipos, tipo de referencias, métodos, campos, etc. Ese número vale más que el espacio de nombre completo, el tipo, el nombre del método y la firma de un método, y es más fácil de manejar. Pero tenga en cuenta que es generado por el compilador y puede ser diferente en cada compilación, por lo que siempre necesita el archivo .pdb de la misma compilación.

El archivo pdb contiene entradas sobre qué compensación de IL en qué método proviene de la ubicación de origen. Si no tiene un StackFrame sino solo un método, probablemente encontrará varias entradas sobre el método para que pueda usar el que tiene el desplazamiento más pequeño o describir el rango completo en el código fuente que define el método.

Éstos son algunos enlaces para ampliar la lectura, el término de búsqueda es "pdb2xml", que es un viejo ejemplo de código de Microsoft:

Desde la API .NET para leer los archivos .pdb es necesario tener los archivos de ensamblado disponibles, esta conversión se debe hacer directamente después de la construcción para mantener el archivo XML generado realmente portátil.

Estoy construyendo este método en mi solución de registro de .NET, FieldLog, para permitir la resolución de la ubicación de origen de los registros de bloqueo de las compilaciones de lanzamiento, y para desactivar las trazas de pila de los ensamblajes ofuscados.

Cuestiones relacionadas