【发布时间】:2021-12-06 10:59:43
【问题描述】:
我尝试使用 !htrace 来检测一些句柄泄漏(我之前在 gflags 用户模式调用堆栈中启用) 问题是,即使它向我显示了句柄分配的调用堆栈,它们的大小也限制为 14 帧。 Windbg 命令“.kframes largeLimit”没有帮助。
【问题讨论】:
标签: windows debugging windbg handle
我尝试使用 !htrace 来检测一些句柄泄漏(我之前在 gflags 用户模式调用堆栈中启用) 问题是,即使它向我显示了句柄分配的调用堆栈,它们的大小也限制为 14 帧。 Windbg 命令“.kframes largeLimit”没有帮助。
【问题讨论】:
标签: windows debugging windbg handle
只有 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 个用户模式条目 你的每一个痕迹听起来都很准确。
内核目前不允许非常深的堆栈跟踪,因为 跟踪数组存储在非分页池中,这是一个非常昂贵的系统 资源。
丹
【讨论】: