【问题标题】:!htrace only shows 14 callstack frames (callstack too short)!htrace 仅显示 14 个调用堆栈帧(调用堆栈太短)
【发布时间】:2021-12-06 10:59:43
【问题描述】:

我尝试使用 !htrace 来检测一些句柄泄漏(我之前在 gflags 用户模式调用堆栈中启用) 问题是,即使它向我显示了句柄分配的调用堆栈,它们的大小也限制为 14 帧。 Windbg 命令“.kframes largeLimit”没有帮助。

【问题讨论】:

    标签: windows debugging windbg handle


    【解决方案1】:

    只有 14 帧是什么意思?
    启用 !htrace 让 htrace 收集跟踪后,你做了足够多的操作吗?
    据我所知,没有 14 帧限制
    只是为了确认我将 cdb 附加到 notepad++ 的运行实例并记录了跟踪

    cdb -pn 记事本++
    !htrace -启用
    .logopen d:\htrace.txt
    g
    打开关闭的几个选项卡,关于插件等可能收集
    用 ctrl+c 恢复
    做了 !htrace 和 quit 和 awk grepped htrace.txt

    我可以在几分钟内看到很多痕迹和帧 > 14 o 日志 1.61 MB 大

    :\>ls -lag *.txt
    -rw-r--r-- 1 197121 1691957 Oct 19 23:01 htrace.txt
    
    :\>awk "/Handle = /" htrace.txt | tail
    Handle = 0x0000000000000484 - CLOSE
    Handle = 0x0000000000000484 - OPEN
    Handle = 0x0000000000000480 - CLOSE
    Handle = 0x0000000000000480 - OPEN
    Handle = 0x000000000000047c - CLOSE
    Handle = 0x000000000000047c - OPEN
    Handle = 0x0000000000000478 - CLOSE
    Handle = 0x0000000000000478 - OPEN
    Handle = 0x0000000000000474 - CLOSE
    Handle = 0x0000000000000474 - OPEN
    
    :\>grep -iE "parse|dump" htrace.txt
    Parsed 0x56C stack traces.
    Dumped 0x56C stack traces.
    
    :\>awk "/Handle =/{print NR-1;NR=0}" htrace.txt | sort | uniq
    13
    14
    15
    16
    17
    18 <<<<<<<<<<<<<
    3
    
    :\>
    

    一个这样的跟踪包含 15 帧,如下所示

    Handle = 0x00000000000004a0 - CLOSE
    Thread ID = 0x0000000000002488, Process ID = 0x0000000000000644
    
    0x00007ffa5769d084: ntdll!NtClose+0x0000000000000014
    0x00007ffa54fe3c56: KERNELBASE!RegCloseKey+0x00000000000000b6
    0x00007ffa566e48d3: shcore!CRegistrySource::Release+0x0000000000000043
    0x00007ffa54962773: windows_storage!CProgidArray::EnumerateCapableFileHandlers+0x00000000000001d3
    0x00007ffa54961ce6: windows_storage!CAssocProgidElement::_GetUserChoice+0x0000000000000082
    0x00007ffa549629ac: windows_storage!CAssocProgidElement::_MapExtensionToUserDefault+0x0000000000000204
    0x00007ffa54962206: windows_storage!CAssocProgidElement::_InitSource+0x0000000000000066
    0x00007ffa5496d6ac: windows_storage!CAssocShellElement::SetKey+0x000000000000005c
    0x00007ffa5495a957: windows_storage!AssocElemCreateForClass2+0x0000000000000083
    0x00007ffa5495a6d1: windows_storage!CFileAssocList::CreateAssoc+0x00000000000000d1
    0x00007ffa5493e17f: windows_storage!CAssocListBase::_GetOrCreate+0x000000000000006f
    0x00007ffa5495e773: windows_storage!CAssocListBase::GetAssoc+0x00000000000000a7
    0x00007ffa5495e657: windows_storage!CFileAssocList::_IsLink+0x0000000000000043
    0x00007ffa5495e5bb: windows_storage!CFileAssocList::GetAssocTable+0x000000000000001b
    0x00007ffa5495ebde: windows_storage!CAssocListBase::EnumerateElements+0x00000000000000de
    --------------------------------------
    Handle = 0x00000000000004a0 - OPEN
    

    根据 ertwhile windbg msdn 新闻组现已消失的帖子,它似乎是硬编码的最大 16 帧 引用引用的副本

    “丹米海 [MSFT]” dmihai@xxxxxxxxxxxxxxxxxxxx 在留言中写道 新闻:%23NGSSnSnGHA.4604@xxxxxxxxxxxxxxxxxxxxxxx

    小修正:!htrace 堆栈跟踪被操作系统内核捕获 (不是ntdll)。最棒的是这些的顺序 痕迹是“完全准确的”。例如,如果进程 A 正在关闭句柄 在进程 B 内部(使用 DuplicateHandle),启用了句柄跟踪 B 你会得到一个跨进程 CLOSE 操作的日志条目。如果堆栈 跟踪将在用户模式下实现(例如在 ntdll 中), 进程 B 的 ntdll 不会得到有关跨进程 CLOSE 的“通知” 并且 B 的句柄将在 !htrace 日志中消失而没有任何痕迹。那 会降低 !htrace 的值。

    堆栈跟踪的最大深度当前被硬编码为 16 (尽管将来可能会改变)。此外,这包括 堆栈跟踪的内核模式部分的一些条目。那些堆栈 内核或驱动程序开发人员可以通过使用显示跟踪条目 !htrace 在内核调试器中。所以得到大约 11 个用户模式条目 你的每一个痕迹听起来都很准确。

    内核目前不允许非常深的堆栈跟踪,因为 跟踪数组存储在非分页池中,这是一个非常昂贵的系统 资源。

    【讨论】:

    • 是的,您可以看到即使您没有完整的调用堆栈,即 RegCloseKey 的帧数有限。堆栈顶部在哪里 - 调用 API 的应用框架?
    • 我想说,调用堆栈的按钮不存在?.
    • 刚刚用谷歌搜索,似乎限制是硬编码的 16 帧编辑帖子并引用了 windbg msdn 新闻组上的旧回复
    猜你喜欢
    • 1970-01-01
    • 2014-11-13
    • 2011-07-02
    • 1970-01-01
    • 2011-01-16
    • 2018-03-18
    • 2017-11-11
    • 2010-11-28
    • 2012-01-27
    相关资源
    最近更新 更多