====== Debugging ====== Guida al debugging di estensioni e applicazioni WvdS FPC RAD Studio. ===== Debug logging ===== ==== Attivazione a due stadi ==== Il debug logging richiede **due condizioni**: - **Compile-time:** Compilare con ''-dDEBUG'' - **Runtime:** Avviare l'estensione con parametro ''--debug'' {$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} ==== File di log ==== * Formato: ''debug-yymmddhhnnss.log'' * Posizione: ''~/binaries/logs/'' * **Mai** committare in ''~/sources/'' ==== Formato MS Exception-Trace ==== Per debugging dettagliato con 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 con 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; ==== Helper call stack ==== 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); (* Formato Unit:Line *) if Info <> '' then Result := Result + ' at ' + Info + #13#10; Frame := get_caller_frame(Frame); end; {$ENDIF} end; ==== Esempio file di log ==== ================================================================================ 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) **Importante:** Mai loggare dati sensibili (token, password) nei parametri! ==== Cosa loggare? ==== ^ Consentito ^ Vietato ^ | Nomi azioni | Token, API key | | Nomi file/percorsi | Password | | Messaggi errore | ID sessione | | Chiavi configurazione | Valori sensibili | ===== Debugging estensioni VS Code ===== ==== Extension Development Host ==== - Aprire il progetto estensione in VS Code - Premere ''F5'' o ''Run > Start Debugging'' - Si apre una nuova finestra VS Code - L'estensione viene caricata li ==== launch.json ==== { "version": "0.2.0", "configurations": [ { "name": "Run Extension", "type": "extensionHost", "request": "launch", "args": [ "--extensionDevelopmentPath=${workspaceFolder}" ], "outFiles": [ "${workspaceFolder}/dist/**/*.js" ] } ] } ==== Breakpoint ==== Poiche il codice viene transpilato (Pascal -> JavaScript), i breakpoint funzionano solo con source map: - Compilare con ''-Jm'' (genera source map) - Impostare breakpoint nel file .pas - VS Code mappa alla posizione JavaScript ===== Output Channel ===== L'Output Channel WvdS mostra i messaggi runtime: - ''View'' -> ''Output'' - Selezionare "WvdS" dal dropdown // Nel codice LogInfo('Messaggio informativo'); LogWarn('Messaggio di avviso'); LogError('Errore: %s', [E.Message]); ===== Developer Console ===== Per debugging a basso livello: - ''Help'' -> ''Toggle Developer Tools'' - Aprire la scheda Console - Errori JavaScript e console.log visibili ===== Problemi comuni ===== ==== L'estensione non si avvia ==== **Diagnosi:** # Verificare i log dell'estensione code --verbose --log trace **Cause frequenti:** * Errori di sintassi nel JavaScript generato * Dipendenze mancanti in package.json * Percorso errato in "main" ==== Il comando non funziona ==== **Diagnosi:** - Aprire Developer Console - Eseguire il comando - Verificare errori **Cause frequenti:** * Comando non in contributes.commands * Handler non registrato * Eccezione nell'handler ==== WebView non mostra nulla ==== **Diagnosi:** - Click destro nella WebView -> "Inspect" - Si aprono i DevTools del browser **Cause frequenti:** * HTML errato * CSP blocca risorse * Errori JavaScript ===== Profiling ===== ==== Misurazione performance ==== {$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 leak ==== pas2js/JavaScript ha garbage collection, ma attenzione a: * Riferimenti circolari con closure * Event handler non rimossi * Array/oggetti grandi in memoria ===== Debug unit test ===== // Test con output di debug 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; ===== Vedi anche ===== * [[.:sicherheit|Linee guida sulla sicurezza]] * [[.:testing|Testing]] * [[.:extension-entwicklung|Sviluppo estensioni]]