!htrace 仅显示 14 个调用堆栈帧(调用堆栈太短)

!htrace only shows 14 callstack frames (callstack too short)

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

只有 14 帧是什么意思?
启用 !htrace 后,htrace 是否进行了足够的操作来收集痕迹?
据我所知没有 14 帧限制
只是为了确认我将 cdb 附加到记事本 ++ 的 运行 实例并记录了痕迹

cdb -pn notepad++
!htrace-启用
.logopen d:\htrace.txt
g
打开关闭几个选项卡关于,插件等可能收集
按 ctrl+c
返回 做了 !htrace 并退出,然后 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 新闻组中现已消失的 post,它似乎是硬编码的最大 16 帧 引用引用的副本

"Dan Mihai [MSFT]" dmihai@xxxxxxxxxxxxxxxxxxxx wrote in message news:%23NGSSnSnGHA.4604@xxxxxxxxxxxxxxxxxxxxxxx

Small correction: the !htrace stack traces are captured by the OS kernel (not ntdll). The greatest thing about that is that the order of these traces is "fully accurate". For example, if process A is closing a handle inside process B (using DuplicateHandle), with handle tracing enabled for B you will get a log entry for the cross-process CLOSE operation. If stack tracing would have been implemented in user-mode (e.g. inside ntdll), process B's ntdll would not get "notified" about the cross process CLOSE and B's handle would go away without any trace in the !htrace log. That would reduce the value of !htrace.

The maximum depth of the stack trace is currently hardcoded to 16 (although it's possible it will change in the future). Also, that includes a few entries for the kernel-mode portion of the stack trace. Those stack trace entries can be displayed by kernel or driver developers by using !htrace in a kernel debugger. So getting around 11 user-mode entries for each of your traces sounds accurate.

The kernel doesn't currently allow very deep stack traces because the array of traces is stored in non-paged pool, a very expensive system resource.

Dan