Comment savoir si un contrôle .Net est visible à l'aide de windbg
Question
J'ai eu un crash qui nous demandait si un contrôle était visible pour l'utilisateur final ou non. En regardant!, Je ne vois pas de champ explicite contenant la valeur true / false correspondant à la propriété Visible, ce qui ne nous surprend pas autant que nous sommes probablement en bas de la zone win32. Est-ce que quelqu'un sait comment déduire ce que Visible aurait renvoyé du fichier de vidage?
merci Oskar
La solution
Ma pensée initiale était qu'il ne s'agissait que de regarder le bon champ, mais en réalité, il a fallu creuser un peu plus. Si vous examinez Contrôle dans Reflector, vous verrez que la propriété Visible appelle GetVisibleCore, qui compare un champ d'état interne à la valeur 2 (qui se trouve être la constante STATE_VISIBLE).
Donc, pour savoir si un contrôle est visible, nous devons localiser le champ d'état et effectuer quelques manipulations de bits.
Si vous avez l'adresse de l'instance, vous pouvez procéder comme suit:
.shell -ci "!do <ADDRESS>" grep state (use findstr, if you don't have grep)
La sortie ressemble à ceci
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
Notez qu'il y a deux champs d'état. Je n'ai pas cherché à savoir pourquoi, mais celui que vous voulez est le System.Int32. Dans mon exemple, la valeur est 17432589.
Le code dans GetState est le suivant
return ((this.state & flag) != 0);
donc tout ce que vous avez à faire ici est (17432589 & amp; 2)! = 0
et vous obtiendrez l'état Visible de l'instance spécifique.
En fait, vous devrez peut-être aller plus loin. Si la réponse ci-dessus est fausse, vous devez rechercher le parent et répéter l'opération. Pour mon exemple simple en utilisant un formulaire qui n'était pas nécessaire.