Debugging

Upute za debugging WvdS FPC RAD Studio Extensiona i aplikacija.

Debug-Logging

Aktivacija u dva koraka

Debug-Logging zahtijeva dva uvjeta:

  1. Compile-Time: Kompilacija s -dDEBUG
  2. Runtime: Pokretanje Extensiona s –debug parametrom
{$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-Datoteka

  • Format: debug-yymmddhhnnss.log
  • Lokacija: ~/binaries/logs/
  • Nikada ne commitajte u ~/sources/

MS Exception-Trace Format

Za detaljno debuggiranje s Call Stackom:

procedure LogDebugTrace(const AMessage: string; const AArgs: array of const);
var
  CallStack: string;
begin
  {$IFDEF DEBUG}
  if not DebugEnabled then Exit;
 
  (* Call Stack s 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;

Primjer Log-Datoteke

================================================================================
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)
Važno: Nikada ne logirajte osjetljive podatke (Tokene, Lozinke) u Parameters!

Što logirati?

Dozvoljeno Zabranjeno
Nazivi akcija Tokeni, API-Ključevi
Nazivi datoteka/putanje Lozinke
Poruke o greškama Session-ID-evi
Konfiguracijski ključevi Osjetljive vrijednosti

VS Code Extension Debugging

Extension Development Host

  1. Otvorite Extension-projekt u VS Code
  2. Pritisnite F5 ili Run > Start Debugging
  3. Otvara se novi VS Code-prozor
  4. Extension se tamo učitava

launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Run Extension",
      "type": "extensionHost",
      "request": "launch",
      "args": [
        "--extensionDevelopmentPath=${workspaceFolder}"
      ],
      "outFiles": [
        "${workspaceFolder}/dist/**/*.js"
      ]
    }
  ]
}

Breakpoints

Budući da je kod transpiliran (Pascal → JavaScript), Breakpoints funkcioniraju samo sa Source Mapsima:

  1. Kompilirajte s -Jm (generiranje Source Map)
  2. Postavite Breakpoints u .pas-datoteci
  3. VS Code mapira na JavaScript-poziciju

Output Channel

WvdS Output Channel prikazuje Runtime-poruke:

  1. ViewOutput
  2. U dropdownu odaberite „WvdS“
// U kodu
LogInfo('Information message');
LogWarn('Warning message');
LogError('Error: %s', [E.Message]);

Developer Console

Za Low-Level-Debugging:

  1. HelpToggle Developer Tools
  2. Otvorite Console-tab
  3. JavaScript-greške i console.log vidljivi

Česti problemi

Extension se ne pokreće

Dijagnoza:

# Provjerite Extension-logove
code --verbose --log trace

Česti uzroci:

  • Sintaksna greška u generiranom JavaScriptu
  • Nedostaju ovisnosti u package.json
  • Pogrešna putanja u „main“

Command ne funkcionira

Dijagnoza:

  1. Otvorite Developer Console
  2. Izvršite Command
  3. Provjerite greške

Česti uzroci:

  • Command nije u contributes.commands
  • Handler nije registriran
  • Exception u Handleru

WebView ništa ne prikazuje

Dijagnoza:

  1. Desni klik u WebViewu → „Inspect“
  2. Otvaraju se Browser DevTools

Česti uzroci:

  • Pogrešan HTML
  • CSP blokira resurse
  • JavaScript-greška

Profiling

Mjerenje performansi

{$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 ima Garbage Collection, ali pazite na:

  • Cirkularne reference s Closures
  • Event-Handleri koji nisu uklonjeni
  • Veliki nizovi/objekti u memoriji

Debugging Unit-Testova

// Test s Debug-izlazom
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;

Vidi također

Zuletzt geändert: 29.01.2026. u 22:36