Cómo saber si un control .Net es visible usando windbg
Pregunta
Obtuve un crashdump en el que estamos debatiendo si un control fue visible para el usuario final o no. Mirando con! No puedo ver ningún campo explícito que contenga el valor verdadero / falso que coincida con la propiedad Visible, lo que no sorprende tanto como probablemente estamos en el territorio de win32. ¿Alguien sabe cómo deducir lo que Visible habría devuelto del archivo de volcado?
gracias Oskar
Solución
Mi pensamiento inicial fue que esto era solo una cuestión de buscar el campo correcto, pero en realidad tomó un poco más de investigación. Si observa Control en Reflector, verá que la propiedad Visible llama a GetVisibleCore, que comprueba un campo de estado interno con el valor 2 (que es la constante STATE_VISIBLE).
Entonces, para averiguar si un control está visible, necesitamos ubicar el campo de estado y hacer algo de manipulación de bits.
Si tiene la dirección de la instancia, puede hacer lo siguiente:
.shell -ci "!do <ADDRESS>" grep state (use findstr, if you don't have grep)
La salida es algo similar a esto
0:000> .shell -ci "!do 015892a4" grep state
03aeedcc 400112c 4c System.Int32 1 instance 17432589 state <=== HERE!
03aeedcc 400112d 50 System.Int32 1 instance 2060 state2
049ac32c 40011ef d0 ...lized.BitVector32 1 instance 01589374 state
03aeedcc 40011f0 ad4 System.Int32 1 static 1 stateScalingNeededOnLayout
03aeedcc 40011f1 ad8 System.Int32 1 static 2 stateValidating
03aeedcc 40011f2 adc System.Int32 1 static 4 stateProcessingMnemonic
03aeedcc 40011f3 ae0 System.Int32 1 static 8 stateScalingChild
03aeedcc 40011f4 ae4 System.Int32 1 static 16 stateParentChanged
Observe que hay dos campos de estado. No he investigado por qué este es el caso, pero el que quieres es el System.Int32. En mi ejemplo, tiene un valor de 17432589.
El código en GetState es el siguiente
return ((this.state & flag) != 0);
así que todo lo que tienes que hacer desde aquí es (17432589 & amp; 2)! = 0
y tendrás el estado visible de la instancia específica.
En realidad, puede que tengas que ir un paso más allá. Si lo anterior devuelve falso, debe buscar al padre y repetir el truco. Para mi ejemplo simple utilizando un formulario que no era necesario.