Share
Beitragsbild zu WinDbg-UI blockiert beim Kopieren: Ursachenforschung führt zu Zwischenablage-Deadlock in virtuellen Umgebungen

WinDbg-UI blockiert beim Kopieren: Ursachenforschung führt zu Zwischenablage-Deadlock in virtuellen Umgebungen

19. Januar 2026

Verzögerung beim Kopieren entpuppt sich als komplexes Synchronisierungsproblem

Ein seit Jahren bestehendes Phänomen beim Windows-Debugger WinDbg konnte nun aufgeklärt werden: Beim Kopieren von Text friert die Benutzeroberfläche für mehrere Sekunden ein. Die Ursache liegt in einem Deadlock der Zwischenablage-Verwaltung, der speziell bei der Ausführung von Windows-VMs unter Linux auftritt.

Entwickler bei Island, einem Unternehmen für Low-Level-OS-Produkte, haben WinDbg permanent im Einsatz. Während einige Teammitglieder von dem Einfrieren berichteten, war es anderen völlig unbekannt. Eine systematische Untersuchung sollte Klarheit schaffen.

Grafik Quelle: Island

Debugging-Strategie: WinDbg debuggt sich selbst

Die Analyse erfolgte durch das Anhängen einer WinDbg-Instanz an eine zweite WinDbg-Instanz. WinDbg läuft in zwei separaten Prozessen: DbgX.Shell.exe verwaltet die Benutzeroberfläche in C#, während EngHost.exe die nativen Debugging-Operationen ausführt. Der UI-Prozess war dabei die Problemquelle.

Der ursprüngliche Plan, während des Einfrierens den Debugger zu unterbrechen und die Callstacks zu analysieren, scheiterte zunächst. Ein interessantes Verhalten zeigte sich: Der übergeordnete Debugger reagierte ebenfalls nicht, solange der untergeordnete Prozess eingefroren war. Nach dem Entsperren zeigten die Callstacks nur wartende Threads in Standard-Windows-Funktionen.

Grafik Quelle: Island

Debug-Ausgaben liefern entscheidenden Hinweis

Der Durchbruch kam durch Debug-Zeichenfolgen, die WinDbg über OutputDebugString ausgibt. Diese zeigten, dass WinDbg die Zwischenablage nicht öffnen konnte und mehrfach Wiederholungsversuche unternahm, bevor der Fehler CLIPBRD_E_CANT_OPEN ausgegeben wurde. Der Text gelangte dennoch in die Zwischenablage.

Die Windows-Zwischenablage erlaubt systemweit nur einem Thread gleichzeitig den Zugriff. Der vorgesehene Ablauf nutzt OpenClipboard() für exklusiven Zugriff, EmptyClipboard() und SetClipboardData() zum Schreiben, GetClipboardData() zum Lesen und CloseClipboard() zur Freigabe.

Grafik Quelle: Island

Ablaufanalyse durch Tracepoints

Durch gezielte Tracepoints an den Zwischenablage-Funktionen ließ sich der Ablauf rekonstruieren:

Der Kopiervorgang läuft zunächst regulär ab. DbgXUI.Utilities.ClipboardHelper.SetClipboardObject() ruft System.Windows.Clipboard.CriticalSetDataObject() auf, welches OleSetClipboard() nutzt. Diese Funktion führt die Zwischenablage-Operationen erfolgreich durch.

Nach Abschluss ruft SetClipboardObject() jedoch System.Windows.Clipboard.Flush() auf. Dieser Aufruf versucht erneut, OpenClipboard() zu nutzen, was fehlschlägt. Über mehrere Sekunden hinweg wiederholt Flush() den Versuch im Hauptthread, was das Einfrieren verursacht.

SPICE Agent als Auslöser identifiziert

Die Frage, wer die Zwischenablage blockiert, führte zum SPICE Agent. Dieser Dienst synchronisiert bei VMs unter Linux Mausposition, Auflösung und Zwischenablage zwischen VM und Host, ähnlich VMware Tools oder VirtualBox Guest Additions.

Tracepoints in vdagent.exe zeigten das Verhalten: Sobald WinDbg Text kopiert, ruft vdagent OpenClipboard() und GetClipboardData(CF_UNICODETEXT) auf. Mehrere Sekunden passiert nichts, während die Zwischenablage geöffnet bleibt. Erst nach CloseClipboard() wird WinDbg wieder reaktiv.

Der Quellcode von vdagent unter gitlab.freedesktop.org zeigte jedoch normales Verhalten ohne offensichtliche Fehler. Das Deaktivieren von SPICE Agent beseitigte das Problem, war aber keine dauerhafte Lösung.

Verzögertes Rendering als Kernmechanismus

Weitere Messungen zeigten, dass GetClipboardData() selbst die lange Ausführungszeit verursacht. Der Grund liegt im verzögerten Rendering der Windows-Zwischenablage-API.

Dieser Mechanismus erlaubt es, Daten in einem Format bereitzustellen, ohne sie sofort zu generieren. Beim Kopieren wird SetClipboardData(format, NULL) aufgerufen, was signalisiert, dass das Format bei Bedarf gerendert wird. Fordert später ein Programm das Format an, erhält die Quelle eine WM_RENDERFORMAT-Nachricht zur synchronen Verarbeitung im UI-Thread.

Der tatsächliche Ablauf:

OleSetClipboard() führt OpenClipboard(), EmptyClipboard() und SetClipboardData(CF_UNICODETEXT, NULL) aus, was verzögertes Rendering aktiviert. Nach CloseClipboard() aktiviert sich vdagent.exe, ruft OpenClipboard() und GetClipboardData(CF_UNICODETEXT) auf und wartet auf das Rendering.

Gleichzeitig versucht DbgXUI.Utilities.ClipboardHelper.SetClipboardObject() Flush() auszuführen und blockiert dabei den UI-Thread. Dies verhindert das verzögerte Rendering. Ein klassischer Deadlock entsteht: Flush() wartet auf die Zwischenablage, während es das Rendering blockiert; vdagent wartet auf das Rendering, während es die Zwischenablage hält.

OleFlushClipboard() wird aufgerufen, um Zwischenablage-Inhalte verfügbar zu machen, falls WinDbg abstürzt. Normalerweise rendert eine Anwendung beim Beenden alle verzögert gerenderten Formate durch WM_RENDERALLFORMATS.

Verantwortlichkeiten schwer zuzuordnen

Die Schuldfrage ist komplex:

WinDbg ruft System.Windows.Clipboard.SetDataObject() mit copy = true im UI-Thread auf. Dieser Parameter veranlasst PresentationCore zu OleFlushClipboard(). Die Ausführung im UI-Thread setzt das Programm Deadlocks aus.

WPF fügt vor Flush() einen Sleep hinzu, was das Zeitfenster für den Deadlock vergrößert. GitHub-Issues 9106 und 9901 im dotnet/wpf-Repository zeigen ähnliche Probleme bei anderen Nutzern.

vdagent registriert lediglich einen Zwischenablage-Monitor und liest bei neuen Daten. Ein GitHub-Kommentar erwähnt ähnliche Deadlocks beim Windows-Zwischenablage-Verlaufsdienst.

Bei 40 Jahren Windows-Ökosystem und Abwärtskompatibilität lässt sich keine generische Lösung ohne Nebenwirkungen vorschlagen.

Praktische Lösung durch Speicher-Patching

Die implementierte Lösung nutzt Windhawk, ein Tool zum Patchen von Programmen im Speicher. Ein Mod hookt OleFlushClipboard() in WinDbg und umgeht die Funktion vollständig. Diese direkte Lösung behebt das unmittelbare Problem.

Grafik Quelle: Island

Offene Fragen bleiben bestehen

Einige Anomalien wurden beobachtet:

NirSofts InsideClipboard mit Auto-Refresh löst den Deadlock nicht aus. Windows-VMs in Hyper-V synchronisieren die Zwischenablage ohne WinDbg-Einfrieren. Ein selbst geschriebenes Testprogramm mit AddClipboardFormatListener() verursacht den Deadlock.

Möglicherweise existiert eine spezifische Methode zum korrekten Überwachen der Zwischenablage, die in der MSDN-Dokumentation nicht erwähnt wird.

Da WinDbg Closed Source ist, könnte dieser Bericht das WinDbg-Team erreichen und zu einer Überprüfung führen, ob SetDataObject() mit copy = true im UI-Thread sinnvoll ist.

Island Enterprise Browser integriert IT-Sicherheit, Netzwerkkontrollen, Datenschutz und App-Zugriff direkt in den Browser für sicheren Anwendungszugriff und optimierte IT-Operationen.

„Die in diesem Beitrag bereitgestellten Informationen wurden sorgfältig recherchiert, erheben jedoch keinen Anspruch auf Vollständigkeit oder absolute Richtigkeit. Sie dienen ausschließlich der allgemeinen Orientierung und ersetzen keine professionelle Beratung. Die Redaktion übernimmt keine Haftung für eventuelle Fehler, Auslassungen oder Folgen, die aus der Nutzung der Informationen entstehen.“

Lesen Sie mehr