====== Debugging ====== Guide to debugging WvdS FPC RAD Studio extensions and applications. ===== Debug Logging ===== ==== Two-Stage Activation ==== Debug logging requires **two conditions**: - **Compile-time:** Compile with ''-dDEBUG'' - **Runtime:** Start extension with ''--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 File ==== * Format: ''debug-yymmddhhnnss.log'' * Location: ''~/binaries/logs/'' * **Never** commit to ''~/sources/'' ==== MS Exception Trace Format ==== For detailed debugging with 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 with 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 File Example ==== ================================================================================ 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) **Important:** Never log sensitive data (tokens, passwords) in Parameters! ==== What to Log? ==== ^ Allowed ^ Forbidden ^ | Action names | Tokens, API keys | | Filenames/paths | Passwords | | Error messages | Session IDs | | Configuration keys | Sensitive values | ===== VS Code Extension Debugging ===== ==== Extension Development Host ==== - Open the extension project in VS Code - Press ''F5'' or ''Run > Start Debugging'' - A new VS Code window opens - The extension is loaded there ==== launch.json ==== { "version": "0.2.0", "configurations": [ { "name": "Run Extension", "type": "extensionHost", "request": "launch", "args": [ "--extensionDevelopmentPath=${workspaceFolder}" ], "outFiles": [ "${workspaceFolder}/dist/**/*.js" ] } ] } ==== Breakpoints ==== Since the code is transpiled (Pascal -> JavaScript), breakpoints only work with source maps: - Compile with ''-Jm'' (generate source map) - Set breakpoints in the .pas file - VS Code maps to the JavaScript position ===== Output Channel ===== The WvdS Output Channel shows runtime messages: - ''View'' -> ''Output'' - Select "WvdS" in the dropdown // In code LogInfo('Information message'); LogWarn('Warning message'); LogError('Error: %s', [E.Message]); ===== Developer Console ===== For low-level debugging: - ''Help'' -> ''Toggle Developer Tools'' - Open Console tab - JavaScript errors and console.log visible ===== Common Problems ===== ==== Extension Does Not Start ==== **Diagnosis:** # Check extension logs code --verbose --log trace **Common causes:** * Syntax error in generated JavaScript * Missing dependencies in package.json * Wrong path in "main" ==== Command Does Not Work ==== **Diagnosis:** - Open Developer Console - Execute command - Check for errors **Common causes:** * Command not in contributes.commands * Handler not registered * Exception in handler ==== WebView Shows Nothing ==== **Diagnosis:** - Right-click in WebView -> "Inspect" - Browser DevTools open **Common causes:** * Wrong HTML * CSP blocks resources * JavaScript error ===== Profiling ===== ==== Performance Measurement ==== {$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 has garbage collection, but watch out for: * Circular references with closures * Event handlers not removed * Large arrays/objects in memory ===== Debugging Unit Tests ===== // Test with debug output 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; ===== See Also ===== * [[.:sicherheit|Security Guidelines]] * [[.:testing|Testing]] * [[.:extension-entwicklung|Extension Development]]