Share via


!list

Die Erweiterung !list führt die angegebenen Debugger-Befehle wiederholt aus, einmal für jedes Element in einer verknüpften Liste.

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

Parameter

Module
Ein optionaler Parameter, der das Modul angibt, das diese Struktur definiert. Wenn die Möglichkeit besteht, dass Typ mit einem gültigen Symbol in einem anderen Modul übereinstimmt, sollten Sie Modul einfügen, um die Zweideutigkeit zu beseitigen.

Type
Gibt den Namen einer Datenstruktur an.

Field
Gibt das Feld an, das den Listenlink enthält. Dabei kann es sich um eine Folge von Feldern handeln, die durch Punkte getrennt sind (mit anderen Worten: Type.Field.Subfield.Subsubfield usw.).

-x „Commands
Gibt die auszuführenden Befehle an. Dies kann eine beliebige Kombination von Debugger-Befehlen sein. Er muss in Anführungszeichen gesetzt werden. Wenn mehrere Befehle angegeben werden, trennen Sie diese durch Semikolons, schließen Sie die gesamte Sammlung von !list-Argumenten in Anführungszeichen ein und verwenden Sie ein Escape-Zeichen ( \ ) vor jedem Anführungszeichen innerhalb dieser äußeren Anführungszeichen. Wenn Befehle weggelassen wird, lautet die Standardeinstellung dp (Display Memory).

-a „Arguments
Gibt die Argumente an, die an den Parameter Commands übergeben werden sollen. Dieser muss in Anführungszeichen gesetzt werden. Argumente kann jede gültige Argumentationskette sein, die normalerweise diesem Befehl folgen darf, mit der Ausnahme, dass Argumente keine Anführungszeichen enthalten darf. Wenn das Pseudoregister $extret in Befehle enthalten ist, kann der Parameter -a „Arguments weggelassen werden.

Options Kann eine beliebige Anzahl der folgenden Optionen sein:

-e
Gibt den Befehl wieder, der für jedes Element ausgeführt wird.

-mMax
Gibt die maximale Anzahl der Elemente an, für die der Befehl ausgeführt werden soll.

StartAddress
Gibt die Adresse der ersten Datenstruktur an. Dies ist die Adresse am Anfang der Struktur, nicht unbedingt die Adresse des Verknüpfungsfeldes.

-h
Zeigt einen kurzen Hilfetext für diese Erweiterung im Fenster Debugger Command an.

DLL

Ext.dll

Hinweise

Die Erweiterung !list durchläuft die verknüpfte Liste und gibt den angegebenen Befehl einmal für jedes Listenelement aus.

Das Pseudoregister $extret wird für jedes Listenelement auf den Wert der Adresse des Listeneintrags gesetzt. Für jedes Element wird die Befehlsfolge Commands ausgeführt. Dieser Befehlsstring kann auf dieses Pseudoregister unter Verwendung der Syntax $extret verweisen. Steht diese nicht im Befehlsstring, wird der Wert der Adresse des Listeneintrags vor der Ausführung an das Ende des Befehlsstrings angehängt. Wenn Sie angeben müssen, wo dieser Wert in Ihrem Befehl erscheinen soll, müssen Sie dieses Pseudoregister explizit angeben.

Diese Befehlsfolge wird so lange ausgeführt, bis die Liste in einem Null-Zeiger endet oder durch eine Schleife zurück zum ersten Element beendet wird. Wenn die Liste in einer Schleife auf ein späteres Element zurückgeht, wird dieser Befehl nicht beendet. Sie können diesen Befehl jedoch jederzeit stoppen, indem Sie CTRL+C in KD und CDB oder Debug | Break oder CTRL+BREAK in WinDbg verwenden.

Jedes Mal, wenn ein Befehl ausgeführt wird, wird die Adresse der aktuellen Struktur als Standardadresse verwendet, wenn der verwendete Befehl optionale Adressparameter hat.

Im Folgenden finden Sie zwei Beispiele für die Verwendung dieses Befehls im Benutzermodus. Beachten Sie, dass die Verwendung im Kernelmodus ebenfalls möglich ist, aber einer anderen Syntax folgt.

Als einfaches Beispiel nehmen Sie an, dass Sie eine Struktur haben, deren Typname MYTYPE ist und die Links in ihren Feldern .links.Flink und .links.Blink hat. Sie haben eine verknüpfte Liste, die mit der Struktur bei 0x6BC000 beginnt. Der folgende Erweiterungsbefehl geht die Liste durch und führt für jedes Element einen dd-L2-Befehl aus. Da für den Befehl dd keine Adresse angegeben wird, nimmt er die Adresse des Listenkopfes als gewünschte Adresse an. Dies bewirkt, dass die ersten beiden DWORDs in jeder Struktur angezeigt werden.

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

Ein komplexeres Beispiel ist die Verwendung von $extret. Sie folgt der Liste vom Typ _LIST_ENTRY auf RtlCriticalSectionList. Für jedes Element werden die ersten vier DWORDS angezeigt, und dann wird die Struktur _RTL_CRITICAL_SECTION_DEBUG angezeigt, die sich an einem Offset von acht Bytes vor dem Element Flink des Listeneintrags befindet.

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