Deadlockerkennung

Die Deadlockerkennung überwacht die Verwendung von Ressourcen, die gesperrt werden müssen– Spinsperren, Mutexes und schnelle Mutexes. Diese Treiberüberprüfungsoption erkennt Codelogik, die zu einem späteren Zeitpunkt zu einem Deadlock führen kann.

Die Deadlockerkennungsoption von Driver Verifier ist zusammen mit der Kerneldebuggererweiterung !deadlock ein effektives Tool, um sicherzustellen, dass Ihr Code eine schlechte Nutzung dieser Ressourcen vermeidet.

Deadlockerkennung wird nur in Windows XP und höheren Versionen von Windows unterstützt.

Ursachen für Deadlocks

Ein Deadlock wird verursacht, wenn zwei oder mehr Threads um eine Ressource in Konflikt geraten, sodass keine Ausführung möglich ist.

Die häufigste Form von Deadlock tritt auf, wenn mindestens zwei Threads auf eine Ressource warten, die dem anderen Thread gehört. Dies wird wie folgt veranschaulicht:

Thread 1 Thread 2
Nimmt Sperre A an Nimmt Sperre B an
Anforderungssperre B Anforderungen sperren A

Wenn beide Sequenzen gleichzeitig ausgeführt werden, erhält Thread 1 nie Die Sperre B, da es sich im Besitz von Thread 2 befindet, und Thread 2 erhält nie Die Sperre A, da es sich im Besitz von Thread 1 befindet. Dies führt bestenfalls dazu, dass die beteiligten Threads angehalten werden und im schlimmsten Fall das System nicht mehr reagiert.

Deadlocks sind nicht auf zwei Threads und zwei Ressourcen beschränkt. Drei-Wege-Deadlocks zwischen drei Threads und drei Sperren sind üblich - und sogar fünfteilige oder sechsteilige Deadlocks treten gelegentlich auf. Diese Deadlocks erfordern ein gewisses Maß an "Pech", da sie auf eine Reihe von Dingen angewiesen sind, die gleichzeitig geschehen. Je weiter die Lock-Akquisitionen jedoch voneinander entfernt sind, desto wahrscheinlicher werden diese.

Einzelthread-Deadlocks können auftreten, wenn ein Thread versucht, eine Sperre zu nehmen, die er bereits besitzt.

Der gemeinsame Nenner aller Deadlocks ist, dass die Sperrhierarchie nicht beachtet wird. Immer wenn mehrere Sperre gleichzeitig erworben werden müssen, sollte jede Sperre eine eindeutige Rangfolge haben. Wenn A an einem Punkt vor B und B vor C an einem anderen Punkt eingenommen wird, lautet die Hierarchie A-B-C. Dies bedeutet, dass A nie nach B oder C erworben werden darf und B nicht nach C erworben werden darf.

Die Sperrhierarchie sollte auch dann befolgt werden, wenn es keine Möglichkeit eines Deadlocks gibt, da es bei der Aufrechterhaltung des Codes leicht ist, dass ein Deadlock versehentlich eingeführt wird.

Ressourcen, die Deadlocks verursachen können

Die eindeutigsten Deadlocks sind das Ergebnis von eigenen Ressourcen. Dazu gehören Spin Locks, Mutexes, schnelle Mutexe und ERESOURCEs.

Ressourcen, die eher signalisiert als abgerufen werden (z. B. Ereignisse und LPC-Ports), verursachen in der Regel viel mehrdeutige Deadlocks. Es ist natürlich möglich und allzu häufig, dass Code diese Ressourcen so missbraucht, dass zwei Threads am Ende unbegrenzt darauf warten, dass sie sich gegenseitig abgeschlossen haben. Da sich diese Ressourcen jedoch nicht im Besitz eines einzigen Threads befinden, ist es nicht möglich, den delinquenten Thread mit einem gewissen Grad an Sicherheit zu identifizieren.

Die Deadlockerkennungsoption von Driver Verifier sucht nach potenziellen Deadlocks, die Drehsperren, Mutexes und schnelle Mutexe umfassen. Sie überwacht weder die Verwendung von ERESOURCEs noch die Verwendung nicht im Besitz von Ressourcen.

Auswirkungen der Deadlockerkennung

Die Deadlock-Erkennungsroutinen des Treiberprüfers finden Verstöße gegen die Sperrhierarchie, die nicht notwendigerweise gleichzeitig sind. In den meisten Fällen identifizieren diese Verstöße Codepfade, die zu einem Deadlock führen, wenn die Chance gegeben wird.

Um potenzielle Deadlocks zu finden, erstellt Driver Verifier ein Diagramm der Ressourcenbeschaffungsreihenfolge und überprüft nach Schleifen. Wenn Sie einen Knoten für jede Ressource erstellen und jederzeit einen Pfeil zeichnen, wenn eine Sperre vor einer anderen abgerufen wird, würden Pfadschleifen Verstöße gegen die Sperrhierarchie darstellen.

Driver Verifier führt eine Fehlerüberprüfung aus, wenn eine dieser Verstöße entdeckt wird. Dies geschieht, bevor es zu tatsächlichen Deadlocks kommt.

Hinweis

Auch wenn die in Konflikt stehenden Codepfade nie gleichzeitig auftreten können, sollten sie dennoch neu geschrieben werden, wenn sie Verstöße gegen die Sperrhierarchie beinhalten. Bei einem solchen Code handelt es sich um einen "Deadlock, der auf den Eintritt wartet", der zu echten Deadlocks führen kann, wenn der Code leicht umgeschrieben wird.

Wenn die Deadlockerkennung einen Verstoß findet, wird eine Fehlerüberprüfung 0xC4 ausgeführt. Der erste Parameter dieser Fehlerüberprüfung gibt den genauen Verstoß an. Mögliche Verstöße sind:

  • Zwei oder mehr Threads, die an einer Verletzung der Sperrhierarchie beteiligt sind

  • Ein Thread, der versucht, ausschließlich eine Ressource zu erwerben, für die sie bereits ein gemeinsamer Besitzer ist (ausschließlich eigene Ressourcen können gemeinsam erworben werden; freigegebene Ressourcen können nicht ausschließlich erworben werden).

  • Ein Thread, der versucht, dieselbe Ressource zweimal zu erhalten (ein Selbst-Deadlock)

  • Eine Ressource, die freigegeben wird, ohne zuvor erworben zu haben

  • Eine Ressource, die von einem anderen Thread als der freigegeben wird, der sie erworben hat.

  • Eine Ressource, die mehr als einmal initialisiert oder gar nicht initialisiert wird

  • Ein Thread, der gelöscht wird, während er weiterhin Ressourcen besitzt

  • Ab Windows 7 kann Driver Verifier mögliche Deadlocks vorhersagen. Beispielsweise versuchen Sie, dieselbe KSPIN_LOCK Datenstruktur sowohl als reguläre Spinsperre als auch als Stapelwarteschlangen-Spinsperre zu verwenden.

Eine Liste der Fehlerüberprüfungsparameter finden Sie unter Fehlerüberprüfung 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION).

Überwachen der Deadlockerkennung

Sobald die Deadlockerkennung einen Verstoß gefunden hat, kann die Kerneldebuggererweiterung !deadlock verwendet werden, um genau zu untersuchen, was aufgetreten ist. Es kann die Topologie der Sperrhierarchie sowie die Aufrufstapel für jeden Thread zum Zeitpunkt des ursprünglichen Abrufs der Sperren anzeigen.

Ein ausführliches Beispiel für die Erweiterung !deadlock sowie allgemeine Informationen zu Debuggererweiterungen finden Sie in der Dokumentation im Paket Debugtools für Windows. Weitere Informationen finden Sie unter Windows-Debuggen .

Aktivieren dieser Option

Hinweis

Diese Option ist nicht kompatibel mit dem Verzögerungsfuzzing der Kernelsynchronisierung.

Sie können die Deadlockerkennungsfunktion für einen oder mehrere Treiber aktivieren, indem Sie den Treiberüberprüfungs-Manager oder die befehlszeile Verifier.exe verwenden. Ausführliche Informationen finden Sie unter Auswählen von Treiberüberprüfungsoptionen.

  • An der Befehlszeile

    In der Befehlszeile wird die Option Deadlockerkennung durch Bit 5 (0x20) dargestellt. Um die Deadlockerkennung zu aktivieren, verwenden Sie den Flagwert 0x20, oder fügen Sie dem Flagwert 0x20 hinzu. Beispiel:

    verifier /flags 0x20 /driver MyDriver.sys
    

    Das Feature ist nach dem nächsten Start aktiv.

    Unter Windows Vista und höheren Versionen von Windows können Sie die Deadlockerkennung auch aktivieren und deaktivieren, ohne den Computer neu zu starten, indem Sie dem Befehl den Parameter /volatile hinzufügen. Beispiel:

    verifier /volatile /flags 0x20 /adddriver MyDriver.sys
    

    Diese Einstellung ist sofort wirksam, geht aber verloren, wenn Sie den Computer herunterfahren oder neu starten. Ausführliche Informationen finden Sie unter Verwenden flüchtiger Einstellungen.

    Die Deadlockerkennungsfunktion ist auch in den Standardeinstellungen enthalten. Beispiel:

    verifier /standard /driver MyDriver.sys
    
  • Verwenden des Treiberüberprüfungs-Managers

    1. Wählen Sie Benutzerdefinierte Einstellungen erstellen (für Codeentwickler) und dann Weiter aus.

    2. Wählen Sie Einzelne Einstellungen aus einer vollständigen Liste auswählen aus.

    3. Wählen Sie (überprüfen) Deadlockerkennung aus.

Die Deadlockerkennungsfunktion ist auch in den Standardeinstellungen enthalten. Um dieses Feature zu verwenden, wählen Sie im Treiberüberprüfungs-ManagerStandardeinstellungen erstellen aus.