如何使用 Windbg 判断 .Net 控件是否可见

发布于 2024-08-08 09:15:13 字数 154 浏览 8 评论 0原文

我收到了一个故障转储,我们正在其中讨论控件是否对最终用户可见。使用 !do 进行查看时,我看不到任何包含与 Visible 属性匹配的 true/false 值的显式字段,这并不奇怪,因为我们可能处于 win32 领域。有谁知道如何推断从转储文件中返回的可见内容?

谢谢 奥斯卡

I got a crashdump where we're debating whether a control was visible to the end user or not. Looking with !do I can't see any explicit field that holds the true/false value matching up with the Visible property, which doesn't surprise that much as we're probably down in win32 teritory. Does anyone know how to deduce what Visible would have returned from the dump file?

thanks
Oskar

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尐籹人 2024-08-15 09:15:13

我最初的想法是这只是一个寻找正确领域的问题,但实际上需要更多的挖掘。如果您查看 Reflector 中的 Control,您会发现 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,则需要查找父级并重复该技巧。对于我使用不必要的表单的简单示例。

My initial thought was that this was just a question of looking up the right field, but actually it took a bit more digging. If you look at Control in Reflector, you'll see that the Visible property calls GetVisibleCore, which checks an internal state field against the value 2 (which happens to be the constant STATE_VISIBLE).

So in order to find out if a control is visible, we need to locate the state field and do some bit manipulation.

If you have the address of the instance, you can do the following:

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

The output is something similar to this

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

Notice, that there are two state fields. I haven't looked into why this is the case, but the one you want is the System.Int32. In my example it has a value of 17432589.

The code in GetState is as follows

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

so all you have to do from here is (17432589 & 2) != 0 and you'll have the Visible state of the specific instance.

Actually, you may have to go a step further. If the above returns false, you need to look up the parent and repeat the trick. For my simple example using a Form that was not necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文