Home > Net >  !htrace only shows 14 callstack frames (callstack too short)
!htrace only shows 14 callstack frames (callstack too short)

Time:10-20

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.

CodePudding user response:

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:#NGSSnSnGHA.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