2012-08-23 47 views
5

Estoy tratando de entender cómo un generador de perfiles de código (en este caso, el Drone Profiler) ejecuta una aplicación .NET de forma diferente a simplemente ejecutarlo directamente. La razón por la que necesito saber esto es porque tengo un problema/corrupción muy extraño con la instalación .NET de mi computadora dev, que se manifiesta fuera del generador de perfiles pero extrañamente no dentro y si puedo entender por qué probablemente pueda solucionar el problema de mi computadora.¿De qué manera la ejecución de la aplicación C# dentro de un generador de perfiles de código difiere de la ejecución de un generador de perfiles de código externo?

El problema SÓLO parece afectar las llamadas a los métodos de System.Net.NetworkInformation (y solo dentro de .NET 3.5 a 2.0, si construyo algo contra 4 todo está bien). Creé una pequeña aplicación de prueba que solo hace una cosa, llama a System.Net.NetworkInformation.IsNetworkAvailable(). Fuera del generador de perfiles aparece "Error de motor de ejecución fatal" en System.dll, y esa es toda la información que proporciona. Por lo que entiendo, ese error generalmente resulta de llamadas a métodos nativos, que presumiblemente ocurren cuando System.dll permite que algunas DLL nativas realicen la lógica IsNetworkAvailable().

  • Me trataron de averiguar el interior y el exterior de la diferencia de perfiles utilizando Process Monitor, grabación de eventos de ambas situaciones y compararlas. Ambos registros fueron los mismos hasta justo después de que se llamaran iphlpapi.dll y winnsi.dll y justo antes de que el código ejecutado por el generador de perfiles dnsapi.dll y el código sin perfil comenzaran a cargar cosas relacionadas con los informes de fallos. En ese momento, cuando parecía ir mal, el código ejecutado por el generador de perfiles creó 4-6 hilos nuevos y el código que no es de perfil (colisión) solo creó 1 o 2. No sé lo que eso significa, en todo caso.

Podría decirse innecesaria fondo

Mi Windows 7 incluye instalación de .NET (a 3.5 a 2,0) estaba trabajando bien hasta que mi disco duro sufrido alguna corrupción y CheckDisk comenzó la búsqueda de clústeres defectuosos. Imaginé el disco a uno nuevo y todo funciona bien, excepto este problema con .NET.

Necesito resolver este problema reinstalando Windows o volviendo a las copias de seguridad de imágenes.

Estas son algunas de las cosas que he mirado en:

  • He diffed los archivos/directorios que parecían más relevantes (las cosas .NET en Archivos de Windows y el Programa) pre- y post-disco problema y no vi ningún cambio donde no esperaba ninguno (no hay corrupción obvia del archivo).
  • He diferido el software y las colmenas del registro del sistema antes y después del disco y no he visto cambios que parezcan relevantes.
  • He creado una nueva cuenta de usuario y he limpiado cualquier variable de entorno en caso de que el entorno estuviera relacionado. Ningún cambio.
  • Hice "sfc/scannow" y no encontró problemas de integridad.
  • Intenté "actualizar ngen" para regenerar el código precompilado en caso de que haya olvidado algo que pueda estar dañado y no haya cambiado nada.
  • Quité mi antivirus para ver si estaba interfiriendo, no hay diferencia.
  • Intenté ejecutar el código de prueba en modo seguro, el mismo problema de bloqueo.

Supongo que necesito reparar mi instalación de .NET pero como Windows 7 incluye .NET 3.5 - 2.0, no puede simplemente volver a ejecutar un instalador de .NET para rehacerlo.No tengo acceso a los discos de Windows para intentar reinstalar Windows sobre sí mismo (la computadora tiene una partición de recuperación pero no se puede usar); también el disco usa una solución de cifrado de disco completo y la reinstalación sería difícil.

No quiero empezar desde cero aquí e instalar un Windows nuevo, reinstalar docenas de paquetes de software, intentar y recordar docenas de personalizaciones/etc relacionadas con el desarrollo.

Teniendo en cuenta todo eso ... ¿alguien tiene algún consejo útil? Necesito .NET 3.5 - 2.0, ya que soy desarrollador y necesito compilarlo y probarlo.

Gracias!

Quinxy

Respuesta

1

La respuesta corta es que mi archivo System.ni.dll estaba dañado, lo reemplacé y todo está bien.

La respuesta larga podría ayudar a otra persona a través de su enfoque a la solución ...

Mi problema relacionado con .Net siendo dañado de tal manera que las aplicaciones no se presentaría excepto a través de un generador de perfiles. Descargué la fuente para el SlimTune open source profiler, la construí localmente y establecí un punto de corte justo antes de la llamada a Process.Start(). Luego comparé todos los parámetros involucrados al iniciar la aplicación con éxito a través del generador de perfiles versus manualmente. La única diferencia significativa que encontré fue la adición de los parámetros del perfil de .NET añadido a las variables de entorno:

  • cor_enable_profiling = 1
  • cor_profiler = {38A7EA35-B221-425a-AD07-D058C581611D}

Luego intenté configurar estos en el entorno de mi propio usuario, y ¡voilá! Ahora cualquier aplicación que ejecutara manualmente funcionaría. (En realidad, había intentado hacer lo mismo unas horas antes, pero utilicé un GUID que se incluyó en un ejemplo y que no apuntaba a un generador de perfiles real y aparentemente .NET sabía que le había dado un GUID falso y no lo hizo ejecutar en modo de perfil.)

Ahora volví y comencé a leer acerca de cómo CLR ejecuta un archivo PE con la esperanza de descubrir por qué era importante que mi aplicación se ejecutara con el perfil habilitado.Aprendí mucho, pero nada que pareciera aplicarse.

Sin embargo, recordé que debería volver a revisar el registro de chkdsk que seguí enumerando los archivos dañados por la falla de la unidad. Después de la falla, convertí todos los identificadores de archivos enumerados en rutas/nombres de archivo y reemplacé todos los más de 100 archivos que pude de la copia de seguridad, pero efectivamente cuando volví atrás y miré, encontré una nota que, aunque había reemplazado 4 o 5. Archivos relacionados con .NET. Existió un archivo que no pude reemplazar porque estaba "en uso". Ese archivo? System.ni.dll !!! Ahora pude reemplazar este archivo de la copia de seguridad y voila mi instalación .NET vuelve a ser normal, las aplicaciones funcionan ya sea con perfil o no.

Lo frustrante es que cuando ocurrió esta incidencia por primera vez, esperaba que el problema se relacionara con un archivo dañado, y específicamente con un archivo llamado System.dll que alojaba los métodos que fallaban. Y entonces diferencié y redifiqué todos los archivos llamados System.dll. Pero no me di cuenta en ese momento que System.ni.dll era una manifestación nativa compilada de System.dll (o somesuch). Y como había difuminado y redifundido los directorios relacionados con .NET y no me había dado cuenta de esto (ni idea de cómo me lo había perdido), había renunciado a ese enfoque.

De todos modos ... en pocas palabras, era un System.ni.dll dañado que causaba mis problemas, uno o más clusters dentro de él tenían su contenido reemplazado con 0x0 y simplemente se manifestaba como el extraño problema I observado.

0

Esto suena como un problema de tiempo, que el generador de perfiles "fijo" por lo que es sólo un poco más lento.

Muchos perfiladores usan instrumentación (more info here), lo que ralentiza levemente la aplicación. Aparentemente, ralentiza un hilo lo suficiente como para que otro hilo pueda hacer un poco más de trabajo, evitando ese bloqueo. Errores como estos a menudo no se manifiestan directamente en la máquina de desarrollo, sino que salen a la superficie tan pronto como se ejecutan en un procesador con más núcleos o hiper-threading. Algunas veces solo ocurren en versiones de lanzamiento (o viceversa en compilaciones de depuración). Los problemas de sincronización pueden ser difíciles de rastrear ya que el mismo código puede dar resultados diferentes en diferentes condiciones (en el perfilador o el depurador).

Desde su descripción voy a tratar de hacer una suposición sobre la forma en que puede ser fija:

Trata de encontrar en la fuente donde se inician los nuevos temas. Luego, una vez que se generan, agregue una línea System.Threading.Thread.Sleep(500); allí para pausar el hilo principal y dar a los nuevos hilos algo de tiempo para comenzar.

Sin el código fuente y algunos rastros de pila de fallas, esto es un poco complicado.

+0

Realmente aprecio la idea y el comentario. Es una hipótesis muy interesante. Creo que parte de lo que dices no puede aplicarse en este caso, dado que mi programa de demostración que manifiesta este problema es literalmente una línea (con un formulario de proyecto Windows Forms predeterminado) que llama a la función Ping(), y todo funcionó perfectamente antes del problema de disco que tuve. Pero la parte que mencionas sobre la instrumentación puede ser muy importante, en particular porque cuando comparé el registro entre los estados de trabajo y no trabajo noté algunos cambios relacionados con los monitores de rendimiento/etc. –

+0

Así que creo que debería echar un vistazo a los cambios en el registro relacionados con los contadores de rendimiento y ver si el cambio hace algo. –

Cuestiones relacionadas