!htrace показывает только 14 кадров стека вызовов (слишком короткий стек вызовов)

#windows #debugging #windbg #handle

Вопрос:

Я пытаюсь использовать !htrace для обнаружения некоторых утечек дескрипторов (я включал их раньше в стеке вызовов пользовательского режима gflags) Проблема в том, что, хотя он показывает мне пакеты вызовов с распределением дескрипторов, их размер ограничен 14 кадрами. Команда Windbg «.kframes biggerLimit» не помогает.

Ответ №1:

что вы имеете в виду, говоря всего о 14 кадрах ?
достаточно ли вы выполняете операций после включения !htrace, чтобы htrace собирал следы ?
насколько я могу судить, нет ограничения на 14 кадров
, просто чтобы подтвердить, что я подключил cdb к запущенному экземпляру notepad и зарегистрировал следы

cdb -pn блокнот
!htrace -включить
.логопен d:htrace.txt
g
открыть закрыл несколько вкладок о , плагины и т.д., Чтобы, возможно, собрать
сломался с помощью ctrl c
сделал !htrace и вышел, и awk захватил htrace.txt

я вижу много следов и кадров > 14 o журнал размером 1,61 МБ в течение нескольких минут

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

похоже, что это жестко закодированный максимум 16 кадров в соответствии с ныне исчезнувшим сообщением из бывшей группы новостей windbg msdn
, цитируемым из копии цитаты

«Дэн Михай [MSFT]», — написал dmihai@xxxxxxxxxxxxxxxxxxxx в сообщении news:#NGSSnSnGHA.4604@xxxxxxxxxxxxxxxxxxxxxxx

Небольшое исправление: трассировки стека !htrace записываются ядром ОС (не ntdll). Самое замечательное в этом то, что порядок этих следов «полностью точен». Например, если процесс A закрывает дескриптор внутри процесса B (с использованием DuplicateHandle), при включенной трассировке дескриптора для B вы получите запись в журнале для операции ЗАКРЫТИЯ между процессами. Если бы трассировка стека была реализована в пользовательском режиме (например, внутри ntdll), ntdll процесса B не получил бы «уведомления» о закрытии перекрестного процесса, и дескриптор B исчез бы без каких-либо следов в журнале !htrace. Это уменьшило бы ценность !htrace.

Максимальная глубина трассировки стека в настоящее время жестко задана до 16 (хотя, возможно, в будущем она изменится). Кроме того, это включает в себя несколько записей для части трассировки стека в режиме ядра. Эти записи трассировки стека могут отображаться разработчиками ядра или драйверов с помощью !htrace в отладчике ядра. Таким образом, получение около 11 записей в пользовательском режиме для каждой из ваших трасс звучит точно.

Ядро в настоящее время не допускает очень глубоких трассировок стека, поскольку массив трассировок хранится в пуле без подкачки, что является очень дорогим системным ресурсом.

Dan

Комментарии:

1. да, как вы можете видеть, даже у вас нет полного набора вызовов, т. е. ограниченного количества кадров для RegCloseKey. Где находится верхняя часть стека — фреймы приложений, которые обращаются к API ?

2. Я хотел сказать, что кнопки стека вызовов нет 🙂.

3. просто погуглил, и, похоже, предел-это жестко закодированные 16 кадров, отредактировал сообщение с цитатой из старого ответа в группе новостей windbg msdn