Debugging

Anleitung zum Debugging von WvdS FPC RAD Studio Extensions und Anwendungen.

Debug-Logging

Zwei-Stufen-Aktivierung

Debug-Logging erfordert zwei Bedingungen:

  1. Compile-Zeit: Kompilieren mit -dDEBUG
  2. 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

  1. Öffnen Sie das Extension-Projekt in VS Code
  2. Drücken Sie F5 oder Run > Start Debugging
  3. Ein neues VS Code-Fenster öffnet sich
  4. 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:

  1. Kompilieren Sie mit -Jm (Source Map generieren)
  2. Breakpoints in der .pas-Datei setzen
  3. VS Code mappt zur JavaScript-Position

Output Channel

Der WvdS Output Channel zeigt Laufzeit-Meldungen:

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

  1. HelpToggle Developer Tools
  2. Console-Tab öffnen
  3. 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:

  1. Developer Console öffnen
  2. Command ausführen
  3. Auf Fehler prüfen

Häufige Ursachen:

  • Command nicht in contributes.commands
  • Handler nicht registriert
  • Exception in Handler

WebView zeigt nichts

Diagnose:

  1. Rechtsklick im WebView → „Inspect“
  2. 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

Zuletzt geändert: den 29.01.2026 um 15:13