- Im Ghostty-Terminalemulator wurde ein schwerwiegendes Speicherleck entdeckt, bei dem bei langem Betrieb mehrere Dutzend GB Speicher belegt werden konnten
- Ursache des Problems war, dass in der nicht standardmäßigen Wiederverwendungslogik für Speicherseiten der
PageList-Struktur munmap nicht aufgerufen wurde und sich dadurch nicht freigegebener Speicher ansammelte
- Weil Claude Code CLI häufig Graph-Ausgaben mit mehreren Codepoints erzeugt, stieg die Nutzung nicht standardmäßiger Seiten stark an, wodurch das Leck in großem Maßstab sichtbar wurde
- Der Fix wurde so umgesetzt, dass nicht standardmäßige Seiten nicht wiederverwendet, sondern sofort freigegeben werden; zur Nachverfolgung und Verifizierung des Lecks wurde außerdem die VM-Tag-Funktion von macOS genutzt
- Der Fix gilt als Behebung des größten Leck-Problems in Ghostty und soll in ein kommendes Release (1.3) aufgenommen werden
Überblick über das Speicherleck in Ghostty
- Einige Nutzer berichteten, dass Ghostty nach langem Betrieb mehr als 37 GB Speicher verwendete
- Das Leck existierte mindestens seit Version 1.0, und erst neuere CLI-Apps erfüllten bestimmte Bedingungen, durch die das Problem sichtbar wurde
- Die Korrektur wurde bereits auf GitHub zusammengeführt und soll in Nightly-Builds sowie im offiziellen Release 1.3 enthalten sein
Aufbau der PageList und Speicherverwaltung
- Ghostty verwendet zum Speichern des Terminalinhalts eine doppelt verkettete Listenstruktur namens PageList
- Jede Seite enthält Daten wie Zeichen, Styles und Hyperlinks
- Seiten werden mit
mmap allokiert und über einen Pool für Seiten in Standardgröße wiederverwendet
- Seiten bis zur Standardgröße werden an den Pool zurückgegeben
- Seiten mit nicht standardmäßiger Größe müssen direkt mit
munmap freigegeben werden
- Die Struktur selbst ist korrekt, doch ein Bug in der Optimierungslogik führte zum Leck
Scrollback-Optimierung und Ursache des Bugs
- Wenn Ghostty das
scrollback-limit überschreitet, wird eine Optimierung ausgeführt, bei der die älteste Seite wiederverwendet wird
- Dadurch steigt die Performance, weil keine neue Seite allokiert und nur Pointer angepasst werden müssen
- Das Problem war, dass dabei nur die Metadaten einer nicht standardmäßigen Seite auf Standardgröße geändert wurden, während der tatsächliche Speicher unverändert blieb
- Bei der späteren Freigabe wurde sie dadurch fälschlich als Standardseite behandelt, sodass
munmap nicht aufgerufen wurde
- Infolgedessen wurden nicht standardmäßige Seiten nicht freigegeben und sammelten sich an, was bei langer Laufzeit zu einem massiven Speicherleck führte
Claude Code und das großflächige Sichtbarwerden des Lecks
- Claude Code CLI erzeugt häufig Graph-Ausgaben mit mehreren Codepoints, wodurch die Nutzung nicht standardmäßiger Seiten zunimmt
- Zudem entsteht viel Scrollback-Ausgabe, sodass sich das Leck schnell ansammelt
- Nach dem Design von Ghostty sollten nicht standardmäßige Seiten nur selten auftreten, doch durch die Eigenschaften von Claude Code ließ sich das Leck in großem Umfang reproduzieren
- Der Entwickler stellte klar, dass dieser Bug kein Problem von Claude Code ist, sondern ein Fehler in der internen Logik von Ghostty
Inhalt des Fixes
Nachverfolgung des Lecks mit VM-Tags
- Mit der VM-Tag-Funktion des Mach-Kernels unter macOS wurden den Speicherallokationen der
PageList spezifische Tags zugewiesen
- Dadurch lassen sich beim Debugging die Speicherbereiche von Ghostty klar identifizieren
- Das half erheblich dabei, die Ursache des Lecks zu finden und den Fix zu verifizieren
- Mit dieser Funktion ließ sich visuell prüfen, ob
PageList-bezogener Speicher freigegeben wurde
System zur Vermeidung von Speicherlecks in Ghostty
- Ghostty erkennt und verhindert Speicherlecks auf verschiedene Weise
- In Debug-Builds und Unit-Tests wird Zigs Leak-Detecting-Allocator verwendet
- In der CI werden alle Tests mit valgrind ausgeführt
- Mit macOS Instruments werden Leaks im Swift-Code geprüft
- GTK-bezogene PRs werden mit Valgrind-GUI-Tests verifiziert
- Dieses Leck trat nur unter bestimmten Bedingungen auf und ließ sich daher mit den bisherigen Tests nicht reproduzieren
- Ein neuer Testfall wurde hinzugefügt, um Regressionen zu verhindern
Fazit
- Bei diesem Vorfall handelt es sich um das bislang größte bekannte Speicherleck in Ghostty
- Auch nach dem Fix soll die Situation durch Nutzerberichte und Reproduktionstests weiter überwacht werden
- Die von der Community bereitgestellten Diagnosedaten und Reproduktionsfälle spielten eine entscheidende Rolle bei der Lösung des Problems
- Es wird betont, dass eine reproduzierbare Umgebung der Schlüssel zur Behebung von Speicherlecks ist
Noch keine Kommentare.