Windbg/sos:查找哪个类具有对对象的静态引用

发布于 2024-12-11 05:10:34 字数 946 浏览 0 评论 0原文

我正在排除内存泄漏问题,发现一个对象被保存在内存中,因为它被字典引用。当我对字典实例执行 !gcroot 时,唯一固定的句柄是 System.Object[] 数组,它本身是无根的:

0:025> !gcroot -nostacks 38ad01f8
DOMAIN(0000000002287D80):HANDLE(Pinned):11e15c0:Root:  00000000123c5018(System.Object[])->
  0000000002f2ab20(System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[MyApp.MyObject, MyApp]])->
  000000004223e6e0(System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[MyApp.MyObject, MyApp]][])->
  0000000038ad01f8(MyApp.MyObject)

这使我得出结论,字典实例由某个类 (. NET 将所有静态字段引用保留在对象数组中)。

但是,现在我陷入困境,因为 !gcroot 和 !refs (来自 sosex)看不到静态字段引用。

我可以在堆中搜索指向地址 2f2ab20 的指针:

0:025> s-q 0 L?0xbfffffff 2f2ab20
00000000`123c76f8  00000000`02f2ab20 00000000`02f2ab78

所以我看到地址 123c76f8 附近的某个结构正在引用我的字典。但我该去哪里呢? 123c76f8 附近的结构必须由 EEClass 结构指向,但 sos/sosex 似乎没有提供解析哪个 EEClass 相关的方法。

如果没有这些信息,我如何找出哪个对象包含静态字典?

I'm troubleshooting a memory leak and found that an object is being held in memory because it is referenced by a dictionary. When I do a !gcroot on the dictionary instance, the only pinned handle is an array of System.Object[] which itself is unrooted:

0:025> !gcroot -nostacks 38ad01f8
DOMAIN(0000000002287D80):HANDLE(Pinned):11e15c0:Root:  00000000123c5018(System.Object[])->
  0000000002f2ab20(System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[MyApp.MyObject, MyApp]])->
  000000004223e6e0(System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[MyApp.MyObject, MyApp]][])->
  0000000038ad01f8(MyApp.MyObject)

This leads me to conclude that the Dictionary instance is being held by a static field on some class (.NET keeps all static field references in an Object array).

However, now I'm stuck because !gcroot and !refs (from sosex) do not see static field references.

I can search the heap for a pointer to the address 2f2ab20:

0:025> s-q 0 L?0xbfffffff 2f2ab20
00000000`123c76f8  00000000`02f2ab20 00000000`02f2ab78

So I see that some structure near the address 123c76f8 is referencing my dictionary. But where do I go from here? The structure near 123c76f8 must be pointed to by an EEClass structure, but sos/sosex don't seem to provide a way to resolve which EEClass is relevant.

Without that information, how can I figure out which object contains a static dictionary?

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

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

发布评论

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

评论(3

别闹i 2024-12-18 05:10:34

进行此类分析的一种选择是使用 NuGet 上的 ClrMD 库编写一个小程序来运行转储或进程。

该程序如下所示:

    DataTarget dataTarget = DataTarget.LoadCrashDump(@"c:\path\to\crash.dmp");
    ClrRuntime runtime = dt.CreateRuntime(@"c:\path\to\mscordacwks.dll");
    ClrHeap heap = runtime.GetHeap();

    foreach (ClrRoot root in heap.EnumerateRoots())
    {
        if (root.Object == 0x0000000002f2ab20)
        {
            Console.WriteLine(root.Kind);
            if (root.Kind == GCRootKind.StaticVar)
                Console.WriteLine(root.Name);
        }
    }

您可以在 DotNet 博客

One option for doing this sort of analysis is to use the ClrMD libraryon NuGet to write a small program to run over a dump or process.

The program would look like this:

    DataTarget dataTarget = DataTarget.LoadCrashDump(@"c:\path\to\crash.dmp");
    ClrRuntime runtime = dt.CreateRuntime(@"c:\path\to\mscordacwks.dll");
    ClrHeap heap = runtime.GetHeap();

    foreach (ClrRoot root in heap.EnumerateRoots())
    {
        if (root.Object == 0x0000000002f2ab20)
        {
            Console.WriteLine(root.Kind);
            if (root.Kind == GCRootKind.StaticVar)
                Console.WriteLine(root.Name);
        }
    }

You can read more about the ClrMD library here on the DotNet blog

新雨望断虹 2024-12-18 05:10:34

我运行该 博客

版本:
Win7 X64 .NET 4

DOMAIN(000000000007E9D0):HANDLE(Pinned):1a17f8:Root:  0000000012381018(System.Object[])->
  0000000002391dc0(System.Collections.ArrayList)->
  0000000002391e78(System.Object[])->
  0000000002391e60(StaticRootedWhere.Fruit)



0:000> s-d 0000000012381018 L?0x2000 0000000002391dc0
00000000`12382fd8  02391dc0 00000000 0238fb30 00000000  ..9.....0.8.....


0:000> s-d 0 L?0xffffffffffffffff 00000000`12382fd8
00000000`00319680  12382fd8 00000000 02009443 00000000  ./8.....C.......
000007ff`000337d8  12382fd8 00000000 00000001 00000000  ./8.............
000007ff`00150160  12382fd8 00000000 24548b48 278ee828  ./8.....H.T$(..'




0:000> !u 000007ff`00150160
Normal JIT generated code
StaticRootedWhere.Program..cctor()
Begin 000007ff00150120, size 59

E:\..........\StaticRootedWhere\Program.cs @ 11:
000007ff`00150120 4883ec38        sub     rsp,38h
000007ff`00150124 48b8f0340300ff070000 mov rax,7FF000334F0h
000007ff`0015012e 8b00            mov     eax,dword ptr [rax]
000007ff`00150130 85c0            test    eax,eax
000007ff`00150132 7405            je      StaticRootedWhere!StaticRootedWhere.Program..cctor()+0x19 (000007ff`00150139)
000007ff`00150134 e817ac51ee      call    clr!JIT_DbgIsJustMyCode (000007fe`ee66ad50)
000007ff`00150139 488d0d58ff07ec  lea     rcx,[mscorlib_ni+0x4d0098 (000007fe`ec1d0098)]
000007ff`00150140 e81b2d0bee      call    clr!JIT_TrialAllocSFastMP_InlineGetThread (000007fe`ee202e60)
000007ff`00150145 4889442420      mov     qword ptr [rsp+20h],rax
000007ff`0015014a 488b442420      mov     rax,qword ptr [rsp+20h]
000007ff`0015014f 4889442428      mov     qword ptr [rsp+28h],rax
000007ff`00150154 488b4c2428      mov     rcx,qword ptr [rsp+28h]
000007ff`00150159 e802b7f5eb      call    mscorlib_ni!System.Collections.ArrayList..ctor() (000007fe`ec0ab860)
000007ff`0015015e 48b9d82f381200000000 mov rcx,12382FD8h
000007ff`00150168 488b542428      mov     rdx,qword ptr [rsp+28h]
000007ff`0015016d e88e270bee      call    clr!JIT_WriteBarrier_Fast (000007fe`ee202900)
000007ff`00150172 eb00            jmp     StaticRootedWhere!StaticRootedWhere.Program..cctor()+0x54 (000007ff`00150174)
000007ff`00150174 4883c438        add     rsp,38h
000007ff`00150178 c3              ret

我把我的结果贴在这里仅供大家参考。这是我读完博客后第二次验证结果。第一次验证没有得到预期的结果。

I run the code that is post on that blog.

version:
Win7 X64 .NET 4

DOMAIN(000000000007E9D0):HANDLE(Pinned):1a17f8:Root:  0000000012381018(System.Object[])->
  0000000002391dc0(System.Collections.ArrayList)->
  0000000002391e78(System.Object[])->
  0000000002391e60(StaticRootedWhere.Fruit)



0:000> s-d 0000000012381018 L?0x2000 0000000002391dc0
00000000`12382fd8  02391dc0 00000000 0238fb30 00000000  ..9.....0.8.....


0:000> s-d 0 L?0xffffffffffffffff 00000000`12382fd8
00000000`00319680  12382fd8 00000000 02009443 00000000  ./8.....C.......
000007ff`000337d8  12382fd8 00000000 00000001 00000000  ./8.............
000007ff`00150160  12382fd8 00000000 24548b48 278ee828  ./8.....H.T$(..'




0:000> !u 000007ff`00150160
Normal JIT generated code
StaticRootedWhere.Program..cctor()
Begin 000007ff00150120, size 59

E:\..........\StaticRootedWhere\Program.cs @ 11:
000007ff`00150120 4883ec38        sub     rsp,38h
000007ff`00150124 48b8f0340300ff070000 mov rax,7FF000334F0h
000007ff`0015012e 8b00            mov     eax,dword ptr [rax]
000007ff`00150130 85c0            test    eax,eax
000007ff`00150132 7405            je      StaticRootedWhere!StaticRootedWhere.Program..cctor()+0x19 (000007ff`00150139)
000007ff`00150134 e817ac51ee      call    clr!JIT_DbgIsJustMyCode (000007fe`ee66ad50)
000007ff`00150139 488d0d58ff07ec  lea     rcx,[mscorlib_ni+0x4d0098 (000007fe`ec1d0098)]
000007ff`00150140 e81b2d0bee      call    clr!JIT_TrialAllocSFastMP_InlineGetThread (000007fe`ee202e60)
000007ff`00150145 4889442420      mov     qword ptr [rsp+20h],rax
000007ff`0015014a 488b442420      mov     rax,qword ptr [rsp+20h]
000007ff`0015014f 4889442428      mov     qword ptr [rsp+28h],rax
000007ff`00150154 488b4c2428      mov     rcx,qword ptr [rsp+28h]
000007ff`00150159 e802b7f5eb      call    mscorlib_ni!System.Collections.ArrayList..ctor() (000007fe`ec0ab860)
000007ff`0015015e 48b9d82f381200000000 mov rcx,12382FD8h
000007ff`00150168 488b542428      mov     rdx,qword ptr [rsp+28h]
000007ff`0015016d e88e270bee      call    clr!JIT_WriteBarrier_Fast (000007fe`ee202900)
000007ff`00150172 eb00            jmp     StaticRootedWhere!StaticRootedWhere.Program..cctor()+0x54 (000007ff`00150174)
000007ff`00150174 4883c438        add     rsp,38h
000007ff`00150178 c3              ret

I post my result here just for your reference. this is my second time to verify the result after reading the blog. The first time verifying is not got the expected result.

╰◇生如夏花灿烂 2024-12-18 05:10:34

本博客中描述了一种方法。该方法的简短解释是您想要找到一段将新元素添加到对象数组中的代码。该对象数组是静态字段数组(在您的情况下为 00000000123c5018 )。该方法的名称应该是 AnOffendingType..ctor(),它是您正在寻找的静态类型构造函数。

One method described in this blog. A short explanation of the method is you want to locate a peice of code that added a new element into an object array. That object array is array of static fields (00000000123c5018 in your case). The name of the method is supposed to be AnOffendingType..ctor(), which is a static type constructor you are looking for.

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