Debugging

Guida al debugging di estensioni e applicazioni WvdS FPC RAD Studio.

Debug logging

Attivazione a due stadi

Il debug logging richiede due condizioni:

  1. Compile-time: Compilare con -dDEBUG
  2. 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

  1. Aprire il progetto estensione in VS Code
  2. Premere F5 o Run > Start Debugging
  3. Si apre una nuova finestra VS Code
  4. 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:

  1. Compilare con -Jm (genera source map)
  2. Impostare breakpoint nel file .pas
  3. VS Code mappa alla posizione JavaScript

Output Channel

L'Output Channel WvdS mostra i messaggi runtime:

  1. ViewOutput
  2. 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:

  1. HelpToggle Developer Tools
  2. Aprire la scheda Console
  3. 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:

  1. Aprire Developer Console
  2. Eseguire il comando
  3. Verificare errori

Cause frequenti:

  • Comando non in contributes.commands
  • Handler non registrato
  • Eccezione nell'handler

WebView non mostra nulla

Diagnosi:

  1. Click destro nella WebView → „Inspect“
  2. 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

Zuletzt geändert: il 29/01/2026 alle 22:36