From 69f9e9952c62504e58a7e5e4be84e4750fea3f27 Mon Sep 17 00:00:00 2001 From: x3 Date: Mon, 21 Sep 2026 23:52:23 +0200 Subject: [PATCH] Crash-Haertung: Delegat bei Programm-Sets abhaengen, send()-Pointer safe, Doku --- Sources/RemminaMac/Services/PTYSession.swift | 5 +++-- Sources/RemminaMac/Views/TerminalInputField.swift | 13 +++++++++++-- docs/ERRORS.md | 13 +++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Sources/RemminaMac/Services/PTYSession.swift b/Sources/RemminaMac/Services/PTYSession.swift index f665002..681f6c2 100644 --- a/Sources/RemminaMac/Services/PTYSession.swift +++ b/Sources/RemminaMac/Services/PTYSession.swift @@ -205,12 +205,13 @@ final class PTYSession: ObservableObject { func send(_ string: String) { let fd = masterFD guard fd >= 0 else { return } - guard let data = string.data(using: .utf8) else { return } + guard let data = string.data(using: .utf8), !data.isEmpty else { return } ioQueue.async { data.withUnsafeBytes { ptr in + guard let base = ptr.baseAddress else { return } var written = 0 while written < data.count { - let n = write(fd, ptr.baseAddress!.advanced(by: written), data.count - written) + let n = write(fd, base.advanced(by: written), data.count - written) if n <= 0 { break } written += n } diff --git a/Sources/RemminaMac/Views/TerminalInputField.swift b/Sources/RemminaMac/Views/TerminalInputField.swift index 1974dfb..0af4dc9 100644 --- a/Sources/RemminaMac/Views/TerminalInputField.swift +++ b/Sources/RemminaMac/Views/TerminalInputField.swift @@ -38,10 +38,19 @@ struct TerminalInputField: NSViewRepresentable { func updateNSView(_ view: NSView, context: Context) { context.coordinator.onSubmit = onSubmit - if let f = view as? NSTextField, f.stringValue != text { - f.stringValue = text + // Delegat während Programm-Sets abhängen: sonst feuert textDidChange synchron + // zurück ins SwiftUI-State — mitten im Render -> Crash ("Modifying state + // during view update"). User-Tippen läuft weiter über den Delegaten. + if let f = view as? NSTextField { + if f.stringValue != text { + f.delegate = nil + f.stringValue = text + f.delegate = context.coordinator + } } else if let tv = view as? NSTextView, tv.string != text { + tv.delegate = nil tv.string = text + tv.delegate = context.coordinator } } diff --git a/docs/ERRORS.md b/docs/ERRORS.md index e29ffb3..79bc3d2 100644 --- a/docs/ERRORS.md +++ b/docs/ERRORS.md @@ -21,6 +21,7 @@ Stand: 2026-09-21 · Version 0.1.0 · macOS arm64 · Swift 5.9+ · Xcode 15+ | 12 | 2026-09-21 | „Immer Verbindung falsch" | User-Report ohne Details (Ziel/Credentials unbekannt) | offen | ⬜ Teils: Editor-Validierung + kopierbarer Fehlerbericht; warte auf Bericht | | 13 | 2026-09-21 | Permission denied trotz richtigem Passwort | Text-Ersetzung im Eingabefeld verfälscht Sonderzeichen | hoch | ✅ behoben — gehärtetes Eingabefeld (alle Ersetzungen aus, 9/9 Tests) | | 14 | 2026-09-21 | Terminal geht, App nicht (gleiches Passwort) | SSH-Agent-Socket fehlt GUI-Prozessen → evtl. Key-Login in Terminal | hoch | ✅ App reicht Agent jetzt durch; Gegenprobe beim User offen | +| 15 | 2026-09-21 | Crash bei Tippen + Senden | Ursache unklar (headless nicht reproduzierbar) | kritisch | ⬜ Gehärtet (v0.5.3); Crash-Log angefragt | --- @@ -198,3 +199,15 @@ ssh -o IdentitiesOnly=yes administrator@sysdaemon.xyz ``` Zweite Zeile erzwingt Passwort-Login ohne Agent — scheitert sie auch im Terminal, war es immer der Agent-Key. **Status:** ✅ App-Seite umgesetzt — warte auf Gegenprobe. + +## #15 — Crash bei Tippen + Senden (User-Report) +**Stand:** „Sobald ich was eintippe und absende, crasht das Programm." Headless nicht reproduzierbar — alle Ebenen einzeln grün. +**Ausgeschlossen per Test:** +- SIGPIPE beim Schreiben (Harness: macOS liefert EIO statt Signal; `send` nach `stop()` überlebt) — Hypothese widerlegt +- View-Schicht (echter Coordinator + NSTextView: Tippen mit Umlauten/Quotes/Paste, Enter, 200 Programm-Sets) — grün +- PTY-Roundtrip, Refused-, Keychain-, TCP-Harness — grün +**Gehärtet (v0.5.3, ohne Beweis dass es DER Crash war):** +- `TerminalInputField.updateNSView`: Delegat bei Programm-Sets abgehängt — sonst feuert `textDidChange` synchron zurück ins State während SwiftUI rendert („Modifying state during view update" → Crash-Kandidat Nr. 1, genau beim Senden: Eingabe wird geleert) +- `PTYSession.send`: Force-Unwrap `baseAddress!` → Guard, Leer-Check +**Weiter nötig bei erneutem Crash:** Console.app → Absturzberichte → neuesten `RemminaMac`-Eintrag öffnen → `Exception Type`, `Termination Reason` und crashed Thread hierher schicken. Damit steht die Stelle fest. +**Status:** ⬜ wartet auf Rückmeldung / Crash-Log.