Как определить, виден ли элемент управления .Net с помощью windbg

У меня есть аварийный дамп, в котором мы обсуждаем, был ли элемент управления виден конечному пользователю или нет. Глядя на !do, я не вижу явного поля, которое содержит значение true/false, совпадающее со свойством Visible, что не так уж удивительно, поскольку мы, вероятно, находимся на территории win32. Кто-нибудь знает, как сделать вывод, что Visible вернул бы из файла дампа?

спасибо Оскар


person Oskar    schedule 22.10.2009    source источник


Ответы (1)


Моя первоначальная мысль заключалась в том, что это был просто вопрос поиска нужного поля, но на самом деле это заняло немного больше времени. Если вы посмотрите на Control в Reflector, вы увидите, что свойство Visible вызывает GetVisibleCore, который проверяет поле внутреннего состояния на соответствие значению 2 (которое оказывается константой STATE_VISIBLE).

Итак, чтобы узнать, виден ли элемент управления, нам нужно найти поле состояния и выполнить некоторые битовые манипуляции.

Если у вас есть адрес экземпляра, вы можете сделать следующее:

.shell -ci "!do <ADDRESS>" grep state   (use findstr, if you don't have grep)

Вывод примерно такой

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

Обратите внимание, что есть два поля состояния. Я не изучал, почему это так, но вам нужен System.Int32. В моем примере он имеет значение 17432589.

Код в GetState выглядит следующим образом

return ((this.state & flag) != 0);

так что все, что вам нужно сделать, это (17432589 & 2) != 0, и вы получите видимое состояние конкретного экземпляра.

На самом деле, вам, возможно, придется пойти еще дальше. Если приведенное выше возвращает false, вам нужно найти родителя и повторить трюк. В моем простом примере с использованием формы не было необходимости.

person Brian Rasmussen    schedule 26.10.2009
comment
очень хорошо, теперь я знаю, что элемент управления был виден (и мой пользователь прав...) и в другом месте подтвердил, что статус сервера в моем процессе не соответствует тому, что сказал элемент управления, поэтому ошибка должна быть где-то посередине :) - person Oskar; 26.10.2009