====== Debugging ====== Anleitung zum Debugging von WvdS FPC RAD Studio Extensions und Anwendungen. ===== Debug-Logging ===== ==== Zwei-Stufen-Aktivierung ==== Debug-Logging erfordert **zwei Bedingungen**: - **Compile-Zeit:** Kompilieren mit ''-dDEBUG'' - **Laufzeit:** Extension starten mit ''--debug'' Parameter {$IFDEF DEBUG} procedure LogDebugTrace(const AMessage: string; const AArgs: array of const); begin if not DebugEnabled then Exit; WriteToDebugLog(Format('[%s] %s', [ FormatDateTime('hh:nn:ss.zzz', Now), Format(AMessage, AArgs) ])); end; {$ENDIF} ==== Log-Datei ==== * Format: ''debug-yymmddhhnnss.log'' * Speicherort: ''~/binaries/logs/'' * **Niemals** in ''~/sources/'' committen ==== MS Exception-Trace Format ==== Für detailliertes Debugging mit Call Stack: procedure LogDebugTrace(const AMessage: string; const AArgs: array of const); var CallStack: string; begin {$IFDEF DEBUG} if not DebugEnabled then Exit; (* Call Stack mit get_caller_frame / get_frame *) CallStack := GetCallStackTrace; WriteToDebugLog(Format( '[%s] %s'#13#10 + ' at %s'#13#10 + ' Parameters: %s', [ FormatDateTime('yyyy-MM-dd hh:nn:ss.zzz', Now), Format(AMessage, AArgs), CallStack, FormatParams(AArgs) ] )); {$ENDIF} end; ==== Call Stack Helper ==== function GetCallStackTrace: string; var Frame: Pointer; Addr: Pointer; Info: string; begin Result := ''; {$IFDEF DEBUG} Frame := get_frame; while Frame <> nil do begin Addr := get_caller_addr(Frame); Info := BackTraceStrFunc(Addr); (* Unit:Line Format *) if Info <> '' then Result := Result + ' at ' + Info + #13#10; Frame := get_caller_frame(Frame); end; {$ENDIF} end; ==== Log-Datei Beispiel ==== ================================================================================ DEBUG LOG: debug-260112143022.log Started: 2026-01-12 14:30:22.001 ================================================================================ [2026-01-12 14:30:22.001] Application started with --debug at TWvdSApplication.Initialize(Application.Main.pas:42) at program.main(extension_main.pas:398) Parameters: (CommandLine='--debug') [2026-01-12 14:30:22.015] Loading configuration at TWvdSToolchainConfigService.LoadFromSettings(Toolchain.ConfigService.pas:156) at TWvdSToolchainConfigService.AutoDetectAll(Toolchain.ConfigService.pas:89) at DoActivate(extension_main.pas:368) Parameters: (ConfigPath='~/.vscode/settings.json') [2026-01-12 14:30:22.042] Service initialized at TWvdSBuildService.Initialize(Build.Service.pas:45) at DoActivate(extension_main.pas:370) Parameters: (ServiceName='BuildService', Mode=debug) ================================================================================ ERROR TRACE (if any): ================================================================================ [2026-01-12 14:30:24.500] ERROR: File not found at ValidateBuildPath(Build.Service.pas:144) at GenerateCleanCommand(Build.Service.pas:174) at OnBuildClean(extension_main.pas:112) Parameters: (Path='~/invalid/path', ValidationResult=False) Exception: EFileNotFound Message: The specified path does not exist Stack Trace: Build.Service.ValidateBuildPath(144) Build.Service.GenerateCleanCommand(179) extension_main.OnBuildClean(112) VSCode.Commands.ExecuteCommand(89) **Wichtig:** Niemals sensible Daten (Tokens, Passwords) in Parameters loggen! ==== Was loggen? ==== ^ Erlaubt ^ Verboten ^ | Aktionsnamen | Tokens, API-Keys | | Dateinamen/Pfade | Passwörter | | Fehlermeldungen | Session-IDs | | Konfigurationskeys | Sensible Werte | ===== VS Code Extension Debugging ===== ==== Extension Development Host ==== - Öffnen Sie das Extension-Projekt in VS Code - Drücken Sie ''F5'' oder ''Run > Start Debugging'' - Ein neues VS Code-Fenster öffnet sich - Die Extension wird dort geladen ==== launch.json ==== { "version": "0.2.0", "configurations": [ { "name": "Run Extension", "type": "extensionHost", "request": "launch", "args": [ "--extensionDevelopmentPath=${workspaceFolder}" ], "outFiles": [ "${workspaceFolder}/dist/**/*.js" ] } ] } ==== Breakpoints ==== Da der Code transpiliert wird (Pascal → JavaScript), funktionieren Breakpoints nur mit Source Maps: - Kompilieren Sie mit ''-Jm'' (Source Map generieren) - Breakpoints in der .pas-Datei setzen - VS Code mappt zur JavaScript-Position ===== Output Channel ===== Der WvdS Output Channel zeigt Laufzeit-Meldungen: - ''View'' → ''Output'' - Im Dropdown "WvdS" wählen // Im Code LogInfo('Information message'); LogWarn('Warning message'); LogError('Error: %s', [E.Message]); ===== Developer Console ===== Für Low-Level-Debugging: - ''Help'' → ''Toggle Developer Tools'' - Console-Tab öffnen - JavaScript-Fehler und console.log sichtbar ===== Häufige Probleme ===== ==== Extension startet nicht ==== **Diagnose:** # Extension-Logs prüfen code --verbose --log trace **Häufige Ursachen:** * Syntaxfehler im generierten JavaScript * Fehlende Abhängigkeiten in package.json * Falscher Pfad in "main" ==== Command funktioniert nicht ==== **Diagnose:** - Developer Console öffnen - Command ausführen - Auf Fehler prüfen **Häufige Ursachen:** * Command nicht in contributes.commands * Handler nicht registriert * Exception in Handler ==== WebView zeigt nichts ==== **Diagnose:** - Rechtsklick im WebView → "Inspect" - Browser DevTools öffnen sich **Häufige Ursachen:** * Falsches HTML * CSP blockiert Ressourcen * JavaScript-Fehler ===== Profiling ===== ==== Performance-Messung ==== {$IFDEF DEBUG} var StartTime: TDateTime; procedure StartTiming(const AOperation: string); begin StartTime := Now; LogDebug('Starting: %s', [AOperation]); end; procedure EndTiming(const AOperation: string); begin LogDebug('Completed: %s in %d ms', [ AOperation, MilliSecondsBetween(Now, StartTime) ]); end; {$ENDIF} ==== Memory Leaks ==== pas2js/JavaScript hat Garbage Collection, aber achten Sie auf: * Zirkuläre Referenzen mit Closures * Event-Handler nicht entfernt * Große Arrays/Objekte im Speicher ===== Unit-Tests debuggen ===== // Test mit Debug-Ausgabe procedure TMyTest.TestFeature; begin {$IFDEF DEBUG} LogDebug('Testing with input: %s', [TestInput]); {$ENDIF} Result := ProcessInput(TestInput); {$IFDEF DEBUG} LogDebug('Result: %s', [Result]); {$ENDIF} CheckEquals(Expected, Result); end; ===== Siehe auch ===== * [[.:sicherheit|Sicherheitsrichtlinien]] * [[.:testing|Testing]] * [[.:extension-entwicklung|Extension-Entwicklung]]