!Список

Расширение !list выполняет указанные команды отладчика несколько раз для каждого элемента в связанном списке.

!list -t [Module!]Type.Field -x "Commands" [-a "Arguments"] [Options] StartAddress 
!list " -t [Module!]Type.Field -x \"Commands\" [-a \"Arguments\"] [Options] StartAddress " 
!list -h 

Параметры

Модуль
Необязательный параметр, указывающий модуль, определяющий эту структуру. Если существует вероятность того, что тип может соответствовать допустимому символу в другом модуле, следует включить модуль , чтобы устранить неоднозначность.

Тип
Задает имя структуры данных.

Поле
Указывает поле, содержащее ссылку списка. Это может быть последовательность полей, разделенных точками (другими словами, Type.Field.Subfield.Subsubfield и т. д.).

-x "Команды"
Указывает выполняемые команды. Это может быть любое сочетание команд отладчика. Он должен быть заключен в кавычки. Если указаны несколько команд, разделите их точкой с запятой, заключите всю коллекцию аргументов !list в кавычки и используйте escape-символ (\ ) перед каждой кавычками внутри этих внешних кавычки. Если команды опущены, значение по умолчанию — dp (display Memory).

-a "Аргументы"
Указывает аргументы для передачи в параметр Commands . Это должно быть заключено в кавычки. Аргументы могут быть любой допустимой строкой аргументов , которая обычно разрешена выполнять эту команду, за исключением того, что аргументы не могут содержать кавычки . Если псевдорегистрация $extret включена в команды, параметр -a "Arguments" может быть опущен.

Параметры могут быть любым количеством следующих параметров:

-e
Эхо выполняет команду для каждого элемента.

-mMax
Указывает максимальное количество элементов для выполнения команды.

StartAddress
Задает адрес первой структуры данных. Это адрес в верхней части структуры, а не обязательно адрес поля ссылки.

-h
Отображает краткий текст справки для этого расширения в окне команды отладчика.

DLL-библиотеки

Ext.dll

Замечания

Расширение !list будет проходить через связанный список и выдавать указанную команду один раз для каждого элемента списка.

Псевдорегистрирующий $extret имеет значение адреса записи списка для каждого элемента списка. Для каждого элемента выполняются команды командной строки. Эта командная строка может ссылаться на этот псевдорегистрирующий регистр с помощью синтаксиса $extret . Если это не отображается в командной строке, значение адреса записи списка добавляется к концу командной строки перед выполнением. Если необходимо указать, где это значение должно отображаться в команде, необходимо явно указать этот псевдорегистрирующий регистр.

Эта последовательность команд будет выполняться до тех пор, пока список не завершится в указателе NULL, или завершится циклом обратно на первый элемент. Если список циклит обратно на более поздний элемент, эта команда не остановится. Однако эту команду можно остановить в любое время с помощью CTRL+C в KD и CDB или Debug | Разрыв или CTRL+BREAK в WinDbg.

Каждый раз при выполнении команды адрес текущей структуры будет использоваться в качестве адреса по умолчанию, если используется команда имеет необязательные параметры адреса.

Ниже приведены два примера использования этой команды в пользовательском режиме. Обратите внимание, что использование режима ядра также возможно, но соответствует другому синтаксису.

В качестве простого примера предположим, что у вас есть структура, имя типа которой — MYTYPE, и которая содержит ссылки в его ссылках .links. Flink и .links. Поля мигания . У вас есть связанный список, начинающийся со структуры по 0x6BC000. Следующая команда расширения будет проходить через список, и для каждого элемента будет выполняться команда dd L2. Так как адрес не указан в команде dd , он будет принимать адрес головы списка в качестве нужного адреса. Это приводит к отображению первых двух DWORD в каждой структуре.

0:000> !list -t MYTYPE.links.Flink -x "dd" -a "L2" 0x6bc00 

В более сложном примере рассмотрим вариант использования $extret. Он следует списку типов _LIST_ENTRY в RtlCriticalSectionList. Для каждого элемента отображается первые четыре DWORDS, а затем отображается структура _RTL_CRITICAL_SECTION_DEBUG, расположенная в смещение 8 байтов до элемента Flink записи списка.

0:000> !list "-t ntdll!_LIST_ENTRY.Flink -e -x \"dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8\" ntdll!RtlCriticalSectionList"
dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8
7c97c0c8  7c97c428 7c97c868 01010000 00000080
   +0x000 Type             : 1
   +0x002 CreatorBackTraceIndex : 0
   +0x004 CriticalSection  : (null)
   +0x008 ProcessLocksList : _LIST_ENTRY [ 0x7c97c428 - 0x7c97c868 ]
   +0x010 EntryCount       : 0x1010000
   +0x014 ContentionCount  : 0x80
   +0x018 Spare            : [2] 0x7c97c100

dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8
7c97c428  7c97c448 7c97c0c8 00000000 00000000
   +0x000 Type             : 0
   +0x002 CreatorBackTraceIndex : 0
   +0x004 CriticalSection  : 0x7c97c0a0
   +0x008 ProcessLocksList : _LIST_ENTRY [ 0x7c97c448 - 0x7c97c0c8 ]
   +0x010 EntryCount       : 0
   +0x014 ContentionCount  : 0
   +0x018 Spare            : [2] 0