.net 如何读取线程或调用堆栈的父线程或父函数

.net 如何读取线程或调用堆栈的父线程或父函数,.net,visual-studio,stack-overflow,windbg,dump,.net,Visual Studio,Stack Overflow,Windbg,Dump,我正试图破解StackOverflowException崩溃转储 调用堆栈如Visual Studio中所示,如下所示: ntdll.dll!RtlAllocateHeap() [Inline Frame] combase.dll!CRetailMalloc_Alloc(IMalloc *) Line 640 combase.dll!CoTaskMemAlloc(unsigned __int64 stcb) Line 459 shell32.dll!CFSFolder::_InitFolder(

我正试图破解StackOverflowException崩溃转储

调用堆栈如Visual Studio中所示,如下所示:

ntdll.dll!RtlAllocateHeap()
[Inline Frame] combase.dll!CRetailMalloc_Alloc(IMalloc *) Line 640
combase.dll!CoTaskMemAlloc(unsigned __int64 stcb) Line 459
shell32.dll!CFSFolder::_InitFolder()
shell32.dll!CFSFolder::_Bind()
shell32.dll!CFSFolder::BindToObject()
shell32.dll!CRegFolder::BindToObject()
shell32.dll!CRegFolder::BindToObject()
shell32.dll!SHBindToObject()
shell32.dll!SHGetAttributesWithBindCtx()
shell32.dll!CShellLink::_IsTargetAnotherLink()
shell32.dll!CShellLink::_LoadIDList()
shell32.dll!CShellLink::_LoadFromStream()
shell32.dll!CShellLink::_LoadFromFile()
shell32.dll!CShellLink::Load(unsigned short const *,unsigned long)
这似乎不是很有趣。但是,在Windbg中,命令
~kb
提供了一些更多信息:

0:040> ~kb
 # RetAddr           : Args to Child                                                           : Call Site
00 00007ffc`9d5f184a : 00000000`000001b0 00000000`00000002 00000000`00000002 00000000`1e492250 : ntdll!RtlAllocateHeap+0xd2
01 (Inline Function) : --------`-------- --------`-------- --------`-------- --------`-------- : combase!CRetailMalloc_Alloc+0x12 [d:\blue\com\combase\class\memapi.cxx @ 640] 
02 00007ffc`9e3dd4fe : 00000000`000001ad 00000000`00000000 00000000`000001ad 00007ffc`9fa30d67 : combase!CoTaskMemAlloc+0x3a [d:\blue\com\combase\class\memapi.cxx @ 459] 
03 00007ffc`9e3dcf2d : 00007ffc`9e561188 00000000`00000000 00000000`1a6053e0 00007ffc`9e561188 : shell32!CFSFolder::_InitFolder+0xd2
04 00007ffc`9e3dc685 : 00000000`1b803198 00007ffc`9e34203d 00000000`1a1a8580 00007ffc`9e3420c0 : shell32!CFSFolder::_Bind+0x9d1
05 00007ffc`9e3de676 : 00000000`1e7c4af4 00007ffc`9e561188 00000000`00000000 00007ffc`9fa30d67 : shell32!CFSFolder::BindToObject+0x664
06 00007ffc`9e3db94c : 00007ffc`9d5f1860 00430072`006f0046 00000000`00000003 ffffffff`fffffffe : shell32!CRegFolder::BindToObject+0x8bd
07 00007ffc`9e3dafda : 00000000`1e638820 00000000`00000000 00000000`1e7c4ae0 00007ffc`9e3dff07 : shell32!CRegFolder::BindToObject+0x687
08 00007ffc`9e40c041 : 00000000`00000000 00000000`1e80c2a0 00000000`00000000 00006567`8ccde5e5 : shell32!SHBindToObject+0x11d
09 00007ffc`9e408a7b : 00000000`1e638820 00000000`1e7c4ae0 00000000`00000001 00000000`00410000 : shell32!SHGetAttributesWithBindCtx+0x1a0
0a 00007ffc`9e40958f : 00000000`00000000 00000000`00000000 00000000`1a1a9630 00000000`00000000 : shell32!CShellLink::_IsTargetAnotherLink+0x7b
0b 00007ffc`9e40886b : 00000000`00000048 00000000`1e6389e0 00000000`00000000 00000000`1a1a96a0 : shell32!CShellLink::_LoadIDList+0x4b
0c 00007ffc`9e40b3f9 : 00000000`00000000 00000000`1e638820 00000000`00000000 00000000`80000000 : shell32!CShellLink::_LoadFromStream+0x2da
0d 00007ffc`9e40b359 : 00007ffc`8d49c3d9 00000000`1a1a99f8 00000000`00003201 00000000`1f95b1e4 : shell32!CShellLink::_LoadFromFile+0x8f
0e 00007ffc`2ea805f9 : 00000000`00000000 00000000`1a1a9d20 00000000`00000000 00000000`1f95b280 : shell32!CShellLink::Load+0x25
0f 00007ffc`2ea80479 : 00000000`1f95b280 00000000`00000000 00000000`1f95b1d8 00000000`00000000 : 0x00007ffc`2ea805f9
10 00007ffc`2ea8036c : 00000000`00000000 00000000`00000000 00000000`1f95b1b8 00000000`022c55e8 : 0x00007ffc`2ea80479
11 00007ffc`2ea802cd : 00000000`1f95b1d8 00007ffc`2e5d4a3c 00000000`00000000 00000000`022c55e8 : 0x00007ffc`2ea8036c
12 00007ffc`2ea7eae2 : 00000000`04233f90 00009ebd`de3821dd 00000000`00000003 00000000`00000003 : 0x00007ffc`2ea802cd
13 00007ffc`2ea7ee80 : 00000000`02619df0 00009ebd`de3821dd 00000000`1f9571c0 00000000`00000003 : 0x00007ffc`2ea7eae2
14 00007ffc`2ea7ee80 : 00000000`02619df0 00009ebd`de3821dd 00000000`1f94ec10 00000000`00000003 : 0x00007ffc`2ea7ee80
15 00007ffc`2ea7ee80 : 00000000`02619df0 00009ebd`de3821dd 00000000`1f946660 00000000`00000003 : 0x00007ffc`2ea7ee80
16 00007ffc`2ea7ee80 : 00000000`02619df0 00009ebd`de3821dd 00000000`1f93e0b0 00000000`00000003 : 0x00007ffc`2ea7ee80
17 00007ffc`2ea7ee80 : 00000000`02619df0 00009ebd`de3821dd 00000000`1f935b00 00000000`00000003 : 0x00007ffc`2ea7ee80
...
ff 00007ffc`2ea7ee80 : 00000000`02619df0 00009ebd`de3821dd 00000000`1f744808 00000000`00000003 : 0x00007ffc`2ea7ee80
这似乎与StackOverflowException(调用堆栈中的调用太多)一致:实际上,内存地址
0x00007ffc'2ea7ee80
-出于格式化原因,我用一个引号替换了backtick-的函数一直在调用自己

现在的问题是:我如何知道这是哪个函数或哪个是父线程

至于Windbg:当我单击最后一个条目(
ff
,DMS已启用)时,我看到以下内容:

0:040> dx Debugger.Sessions[0].Processes[10912].Threads[5268].Stack.Frames[255].SwitchTo();dv /t /v
Debugger.Sessions[0].Processes[10912].Threads[5268].Stack.Frames[255].SwitchTo()
Unable to enumerate locals, Win32 error 0n318
Private symbols (symbols.pri) are required for locals.
Type ".hh dbgerr005" for details
供您参考:在VisualStudio的
并行堆栈
窗口中,我没有看到引用此线程的线程

有人有想法吗?

提前感谢

调用堆栈中的裸地址意味着代码不在任何加载的模块中

这可能有几个原因:

  • 代码可能是在运行时生成的,就像一个应用程序的情况一样
  • 代码可能位于已卸载的模块中
  • 调用堆栈可能已损坏
  • 当涉及.NET时,它通常是第一个原因——它是JIT代码。 这是非常容易检查使用

    首先使用
    .loadby sos clr
    加载扩展,然后使用
    检查相关指令指针或返回地址!ip2md 0x00007ff`c2ea802cd

    如果是JIT的.NET代码,那么您可能需要熟悉SOS扩展提供的调试问题的方法

    如上所述,您可以使用
    lm
    命令检查卸载的模块(原因#2),并查找卸载的模块

    您可以通过以下方式获得有关内存地址的一般信息:
    !地址0x00007ff`c2ea802cd
    。 如果页面没有
    page\u EXECUTE
    protections或类似的功能,我认为调用堆栈是假的(原因3)


    注意:还有其他JIT运行时。它们在虚拟机、脚本语言甚至一些库(如正则表达式引擎)中非常常见。这些运行时往往不提供调试器扩展,因此,如果您怀疑正在使用调试器扩展,您可能必须为该特定运行时寻找工具。

    在调用堆栈中看到裸地址意味着该代码不在模块中。当涉及.NET时,这通常意味着它是JIT代码。您可能会有一些运气与命令,这是该命令的一部分。正在运行
    .loadby sos clr
    ,后跟
    !ip2md 0x00007ffc2ea802cd
    告诉你什么吗?因为这是.NET,很可能是JITted代码,请使用SOS扩展(
    .loadby SOS clr
    )和
    !dumpstack
    命令。旁注:
    kb
    由于调用约定不同,在大多数情况下对64位无效
    k
    应该足够了。@seanline:我启动了以下两个命令:
    !ip2md 0x00007ffc'2ea7eae2
    !ip2md 0x00007ffc的2ea7ee80
    表示两次相同的结果,在相应的源代码中,我确实看到一个函数在调用自己,这很可能是这个问题的根本原因。请把你的意见写在答复中,这样我就可以接受了。