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

Viewed 79

I try to use !htrace to detect some handle leaks (I enable before in gflags user mode callstack) The problem is that even though it shows me callstacks of handle allocation their size is limited to 14 frames. Windbg command ".kframes biggerLimit" does not help.

1 Answers

what do you mean by only 14 frames ?
do you do enough operations after you enable !htrace for htrace to collect traces ?
as far as i can tell there is no 14 frame limit
just to confirm i attached cdb to a running instance of notepad++ and logged the traces

cdb -pn notepad++
!htrace -enable
.logopen d:\htrace.txt
g
open closed several tabs about , plugins etc to possibly collect
broke back with ctrl+c
did !htrace and quit and awk grepped the htrace.txt

i can see a lot of traces and frames > 14 o a log 1.61 MB big for a few minutes

:\>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

:\>

one such trace contaning 15 frames as below

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

it appears to be a hardcoded max of 16 frames according to the now disappeared post from ertwhile windbg msdn newsgroup quoting from a copy of the quote

"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

Related