!list
La extensión !list ejecuta de forma repetida los comandos del depurador especificados, una vez por cada elemento de una lista vinculada.
!list -t [Module!]Type.Field -x "Commands" [-a "Arguments"] [Options] StartAddress
!list " -t [Module!]Type.Field -x \"Commands\" [-a \"Arguments\"] [Options] StartAddress "
!list -h
Parámetros
Módulo
Parámetro opcional que especifica el módulo que define esta estructura. Si existe la posibilidad de que Type coincida con un símbolo válido en un módulo diferente, debe incluir Module para eliminar la ambigüedad.
Tipo
Especifica el nombre de una estructura de datos.
Campo
Especifica el campo que contiene el vínculo de lista. Esto puede ser realmente una secuencia de campos separados por puntos (en otras palabras, Type.Field.Subfield.Subsubfield, etc.).
-x "Comandos"
Especifica los comandos que se van a ejecutar. Puede ser cualquier combinación de comandos del depurador. Debe escribirse entre comillas. Si se especifican varios comandos, separe con punto y coma, incluya toda la colección de argumentos !list entre comillas y use un carácter de escape ( \ ) antes de cada par de comillas dentro de estas comillas externas. Si se omite Commands, el valor predeterminado es dp (Memoria de visualización).
-a "Argumentos"
Especifica los argumentos para pasar al parámetro Commands. Este debe escribirse entre comillas. Losargumentos pueden ser cualquier cadena de argumento válida que normalmente pueda seguir este comando, salvo que los argumentos no pueden contener comillas. Si el pseudo registro $extret se incluye en Commands, el parámetro -a "de argumentos" se puede omitir.
Opciones Puede ser cualquiera de las siguientes opciones:
-e
Repite el comando que se ejecuta para cada elemento.
-m Max
Especifica el número máximo de elementos para los que se va a ejecutar el comando.
StartAddress
Especifica la dirección de la primera estructura de datos. Esta es la dirección en la parte superior de la estructura, no necesariamente la dirección del campo de vínculo.
-h
Muestra un breve texto de ayuda para esta extensión en la ventana de comando del depurador.
Archivo DLL
Ext.dll
Comentarios
La extensión !list pasará por la lista vinculada y emitirá el comando especificado una vez para cada elemento de lista.
El pseudo registro $extret se establece en el valor de la dirección de entrada de lista para cada elemento de lista. Para cada elemento, se ejecuta la cadena Commands. Esta cadena de comandos puede hacer referencia a este pseudo registro mediante la sintaxis $extret. Si esto no aparece en la cadena de comandos, el valor de la dirección de entrada de lista se anexa al final de la cadena de comandos antes de la ejecución. Si necesita especificar dónde debe aparecer este valor en el comando, debe especificar este pseudo registro de forma explícita.
Esta secuencia de comandos se ejecutará hasta que la lista finalice en un puntero nulo, o finalizará haciendo un bucle en el primer elemento. Si la lista vuelve a un elemento posterior, este comando no se detendrá. Sin embargo, puede detener este comando en cualquier momento mediante CTRL+C en KD y CDB, o Depurar | Interrumpir o CTRL+INTERRUMPIR en WinDbg.
Cada vez que se ejecuta un comando, la dirección de la estructura actual se usará como dirección predeterminada si el comando que se usa tiene parámetros de dirección opcionales.
A continuación se muestran dos ejemplos de cómo utilizar este comando en modo de usuario. Tenga en cuenta que el uso en modo kernel también es posible, pero sigue una sintaxis diferente.
Como ejemplo sencillo, supongamos que tiene una estructura cuyo nombre de tipo es MYTYPE y que tiene vínculos dentro de sus campos .links. Flink y .links.Blink. Tiene una lista vinculada que comienza con la estructura en 0x6BC000. El siguiente comando de extensión pasará por la lista y para cada elemento ejecutará un comando dd L2. Dado que no se especifica ninguna dirección en el comando dd tomará la dirección del encabezado de lista como dirección deseada. Esto hace que se muestren los dos primeros DWORD en cada estructura.
0:000> !list -t MYTYPE.links.Flink -x "dd" -a "L2" 0x6bc00
Como ejemplo más complejo, considere el caso de usar $extret. Sigue la lista de tipos _LIST_ENTRY en RtlCriticalSectionList. Para cada elemento, muestra las cuatro primeras DWORDS y, a continuación, muestra la estructura _RTL_CRITICAL_SECTION_DEBUG ubicada en un desplazamiento de ocho bytes antes del elemento Flink de la entrada de lista.
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