Come sapere se un controllo .Net è visibile usando windbg
Domanda
Ho avuto un crashdump in cui stiamo discutendo se un controllo fosse visibile o meno all'utente finale. Guardando! Non riesco a vedere nessun campo esplicito che contenga il valore vero / falso corrispondente alla proprietà Visible, il che non sorprende tanto quanto probabilmente siamo in down32 teritory. Qualcuno sa come dedurre ciò che Visible avrebbe restituito dal file di dump?
grazie Oskar
Soluzione
Il mio pensiero iniziale era che si trattava solo di cercare il campo giusto, ma in realtà è stato necessario scavare un po 'di più. Se guardi Control in Reflector, vedrai che la proprietà Visible chiama GetVisibleCore, che controlla un campo di stato interno rispetto al valore 2 (che risulta essere la costante STATE_VISIBLE).
Quindi, per scoprire se un controllo è visibile, dobbiamo localizzare il campo state e fare un po 'di manipolazione dei bit.
Se si dispone dell'indirizzo dell'istanza, è possibile effettuare le seguenti operazioni:
.shell -ci "!do <ADDRESS>" grep state (use findstr, if you don't have grep)
L'output è qualcosa di simile a questo
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
Si noti che esistono due campi stato. Non ho esaminato il motivo per cui questo è il caso, ma quello che vuoi è System.Int32. Nel mio esempio ha un valore di 17432589.
Il codice in GetState è il seguente
return ((this.state & flag) != 0);
quindi tutto ciò che devi fare da qui è (17432589 & amp; 2)! = 0
e avrai lo stato Visibile dell'istanza specifica.
In realtà, potresti dover fare un passo ulteriore. Se quanto sopra restituisce false, è necessario cercare il genitore e ripetere il trucco. Per il mio semplice esempio usare un modulo che non era necessario.