Files

95 lines
9.4 KiB
Markdown

# Verification Report: phase-5-06-debugger-und-direktfenster
Stand: 2026-09-06. Proposal, Design, alle 16 Aufgaben und alle sieben
Anforderungen mit elf Szenarien wurden gegen die Implementierung geprüft.
## Ergebnis
| Dimension | Ergebnis |
| --- | --- |
| Completeness | 16/16 Aufgaben, 7/7 Anforderungen |
| Correctness | 11/11 Spec-Szenarien durch ausführbare Prüfungen abgedeckt |
| Coherence | Gemeinsamer Compiler, dieselbe VM, vorhandene Dokument-/Sitzungspfade |
| Offene Befunde | 0 CRITICAL, 0 WARNING, 0 SUGGESTION |
## Anforderungen und Szenarien
VM-Nachweise: `crates/tb-vm/tests/debugger.rs` (14 Integrationstests).
IDE-Nachweise: `crates/tb-ide/tests/debugger.rs` (6 Integrationstests mit
App-Kommandos, Tastatur/Maus, TestBackend und tatsächlicher Sitzung).
| Requirement / Scenario | Implementierung | Ausführbarer Nachweis |
| --- | --- | --- |
| Dateigenaue Breakpoints / Zwei Includes mit gleicher Zeile | `Vm::add_source_breakpoint`, `statement_locations`, `debug_boundary`; IDE-Marken mit Dokument-/Ursprungsmodul-ID | VM `include_identity_qualified_globals_udts_and_older_frames`; IDE `includes_and_deleted_marks_do_not_bind_to_foreign_statements`: nur zweites Include, richtiger Quellort und unveränderter Wert vor der Anweisung. |
| Dateigenaue Breakpoints / Einfügen oberhalb einer Marke | `documents::remap_breakpoints`, gemeinsame Edit-/Undo-Transaktionen, `bind_debug_breakpoints` | IDE `dispatcher_marks_edits_rebind_and_readonly_watches` und `includes_and_deleted_marks_do_not_bind_to_foreign_statements`: Verschieben, Neubinden, Kommentarzeile, Löschen und Undo; inaktive Marken sind sichtbar. |
| Schrittsteuerung und Calls / Rekursion und Prozedurschritt | `step_over` mit Frame-ID und GOSUB-Tiefe; `debug_frames`, `select_debug_frame`; F8/F10 | VM `step_over_recursive_frames_history_and_safe_jump`, `gosub_step_over_breakpoint_priority_and_temporary_target_cleanup`, `form_event_breakpoint_and_step_over_keep_the_event_frame`; IDE `calls_procedure_step_cursor_history_and_restart`, `calls_mouse_inspection_instant_key_delete_and_error_window`, `form_handler_keys_and_old_revision_cursor_guard`. |
| Schrittsteuerung und Calls / Temporäres Laufziel | `run_to_cursor`, `cancel_motion`, IDE-Pause und Sitzungsende | VM `gosub_step_over_breakpoint_priority_and_temporary_target_cleanup`; IDE F7 in `calls_procedure_step_cursor_history_and_restart`. Dauerhafte Breakpoints bleiben erhalten; der unterbrochene Cursorlauf wird nicht später erneut wirksam. |
| Watches und Watchpoints / Beobachtung im lokalen Kontext | `sema::lower_debug`, `DebugCompiler`, `evaluate_watch`; ursprüngliche Slots und Link-Mappings, getrennte Frameauswahl | VM `watches_immediate_byref_and_errors_preserve_continuation`, `include_identity_qualified_globals_udts_and_older_frames`, `watches_never_initialize_arrays_or_run_user_functions_and_keep_selected_context`: CINT, lokale Arrays, UDT-Felder, qualifizierte Globals, ältere rekursive Frames, keine Auto-DIM-/Funktions-/ERR-Nebenwirkungen. IDE Calls-Mausauswahl, Shift+F9, Watchfehler und Löschdialog. |
| Watches und Watchpoints / Watchpoint wird wahr | `evaluate_condition`, `check_watchpoints`, gebundener erreichbarer Inspektionsframe; nur aktive Einträge werden ausgewertet | VM `watchpoint_history_ring_and_error_differential`; IDE `immediate_wait_run_transition_watchpoint_and_trace_are_session_owned`: Halt direkt hinter der Zuweisung, aktualisierter Wert. Nicht numerische oder fehlerhafte Bedingungen lösen keinen Halt aus. |
| Direktfenster / Wert ändern und fortsetzen | `start_immediate`, temporärer Frame mit referenzierten Originalslots, gemeinsame VM-Ausführung und `finish_immediate` | VM `watches_immediate_byref_and_errors_preserve_continuation`: lokale Zuweisung, BYREF-Aufruf, PRINT, Original-PC und fortgesetzter geänderter Wert. IDE `dispatcher_marks_edits_rebind_and_readonly_watches` bedient den tatsächlichen Eingabepfad. |
| Direktfenster / Fehler im Direktfenster | Bestehendes `handle_error`, abgegrenzter Debug-Eintritt, Handler-/RESUME-Rückkehr und Quellort `<Immediate>` | VM `immediate_handler_resume_and_break_on_errors`, `immediate_wait_interrupt_nested_error_end_and_run`, `immediate_handler_exit_and_cached_new_imports_are_safe`: ERROR, lokaler/geerbter Handler, RESUME NEXT, Handlerende, INPUT/Warten, Interrupt, END und RUN. IDE Direktfehleranzeige, Warte-/F5-Folge und echter RUN-Sitzungsreset. |
| Trace und Ausführungshistorie / Historie betrachten | `record_debug_execution`, 1.024-Einträge-Ring, Trace-Quellnavigation, H-/I-/Ausführungsmarken | VM `watchpoint_history_ring_and_error_differential`, `same_line_calls_and_immediate_do_not_retrigger_a_line_breakpoint`; IDE `calls_procedure_step_cursor_history_and_restart`: zweimal zurück, vorwärts, unveränderter PC und unveränderte aktuelle Watchwerte, Reset. History führt nur Quellorte, keine rückspielbaren Zustände. |
| Break on Errors / Behandelter Fehler | Halt nach Handlerwahl/Unwinding an dessen erster Statement-Grenze; gesicherte Ursache, ERR/ERL und RESUME-PC | VM `watchpoint_history_ring_and_error_differential` vergleicht den Lauf mit und ohne Halt; `immediate_handler_resume_and_break_on_errors` und `immediate_wait_interrupt_nested_error_end_and_run` prüfen geerbte/lokale Handler und Fortsetzungsrahmen. |
| Sicheres Set Next Statement / Gültiger und ungültiger Sprung | Statement-Tabelle, strukturierte AST-Kontrollpfade und Bytecode-Schleifenbereiche; vollständige Prüfung vor PC-Änderung | VM `step_over_recursive_frames_history_and_safe_jump`, `set_next_rejects_loop_gosub_handler_and_pending_operations_atomically`, `set_next_rejects_else_and_case_entry_but_allows_peer_statements`: gleichrangiger Sprung wirksam; fremde Prozedur, Schleife, ELSE/CASE und GOSUB abgewiesen ohne Teiländerung. IDE `form_handler_keys_and_old_revision_cursor_guard` prüft den Revisionsschutz. |
## Coherence
- Ein Interpreter: Watches benutzen den regulären Lexer/Parser, Sema, Codegen
und die vorhandenen VM-Instruktionen. Es gibt keine zweite Arithmetik oder
Konvertierungsschicht. Reinheit wird vor Ausführung am erzeugten Bytecode
geprüft; automatische Beobachtung startet weder Host-Polling noch Fehlerhandler.
- Originale Modul-/Zeilen-Breakpoint-APIs bleiben erhalten. Neue Debuggerpfade
sind opt-in; der CLI-Runtimepfad, das TBC-Format und seine Quelldaten bleiben
unverändert. IDE-Compiler behalten vollständige Importkontexte für spätere
Direktaufrufe auch nach inkrementeller Übersetzung.
- Dokumentmarken verwenden dieselben Edits und Undo-Einheiten wie der Editor.
Formularname und Dateiname dürfen verschieden sein. Cursorziele werden nur
gegen die unveränderte pausierte Kompilatrevision akzeptiert.
- Direktkommandos benutzen den bestehenden kooperativen Poll-/Warte-/RUN-Pfad.
Handlerende entfernt keine Locals eines pausierten Frames. Syntaxfehler
mutieren nichts; Laufzeitnebenwirkungen bleiben ausdrücklich wirksam.
- Die Grenzen für reine Watches, History ohne Zeitreise sowie konservatives
Set Next Statement sind in `docs/ide-bedienung.md` dokumentiert. Die
gemeinsame Phase-5-Abnahme bleibt Change 08; native Erzeugung bleibt Phase 6.
## Behobene Verifikationsbefunde
- Zeilenbreakpoints merken ihren letzten Eintritt pro Frame. Ein zurückkehrender
Aufruf oder Direktcode löst keinen zweiten Halt auf derselben Doppelpunktzeile
aus; spätere Schleifendurchläufe halten weiterhin.
- History nimmt eine Grenze erst beim tatsächlichen Ausführen auf. Die vor
einem Direktkommando noch nicht ausgeführte Grenze bleibt danach erhalten.
- Break on Errors markiert den ersten Handler-Einstieg, nicht einen veralteten
Fehler-PC nach dem Unwinding. Ereigniszustellung verschiebt diesen Halt nicht.
- Direktfehler benutzen eine gesicherte Kommando-Rückkehr; auch Handlerende
ohne RESUME erhält die ursprünglichen Frame-Slots und den Fortsetzungspunkt.
- ELSE-/CASE-Arme bekommen eigene Kontrollkontexte. Ein gleicher Frame allein
reicht nicht zur Freigabe von Set Next Statement.
- Include-Marken behalten ihr Ursprungsmodul; Formularmarken benutzen die
Dokumentidentität statt der Annahme, Formularname und Dateiname seien gleich.
- Automatische Watches führen kein Auto-DIM oder Benutzerfunktionen aus;
Fehler verändern ERR nicht. Watchpoints berücksichtigen ihren ausgewählten
erreichbaren Frame und zeigen Fehler pro Eintrag.
- Gewöhnliches STOP/Pause erhält den bisherigen Output-Fokus. Spezifische
Debuggerhalte navigieren zum Quelltext; die vorhandenen Ausgabetests bleiben
unverändert. Die alte Platzhalter-Erwartung „folgt in 06“ wurde durch die
Verfügbarkeit des implementierten Kommandos ersetzt.
## Abschlussprüfungen
- `cargo test --workspace`: 587 bestanden, 0 fehlgeschlagen, 2 bestehende
Ignore-Fälle (Golden-Output-Generator und externe VBDOS-Referenzsuite).
Enthalten sind alle VM-/Fehlerhandler-/CLI-/IDE-Regressionen sowie die
20 neuen Debugger-Integrationstests.
- `cargo clippy --workspace --all-targets -- -D warnings`: bestanden.
- `cargo fmt --all -- --check`: bestanden.
- `git diff --check`: bestanden.
- `openspec validate --all --strict`: 23/23 gültig; bestehende INFO-Hinweise
zur Länge von Requirement-Texten sind keine Validierungsfehler.
Keine angeforderte Prüfdimension wurde ausgelassen. Die Prüfungen sind
reproduzierbar und headless; Maus-/Tasten- und Renderingpfade wurden über
App-Ereignisse und TestBackend geprüft. Es bestehen keine offenen Befunde.
Der Change ist vollständig umgesetzt und zur separaten Synchronisierung und
Archivierung bereit.