[CmdletBinding()] param( [string]$BuildPreset = "windows-msvc-default", [string]$Configuration = "Debug", [string]$Executable = "", [string]$DebuggerCommand = "", [string]$LogDir = "out/logs/debugger", [int]$StartupSmokeSeconds = 20, [switch]$BreakOnFirstChanceAccessViolation, [switch]$LeaveRunning ) $ErrorActionPreference = "Stop" function Resolve-CdbPath { if ($DebuggerCommand.Length -gt 0) { return $DebuggerCommand } $candidates = @( "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe", "C:\Program Files\Windows Kits\10\Debuggers\x64\cdb.exe" ) foreach ($candidate in $candidates) { if (Test-Path -LiteralPath $candidate) { return $candidate } } throw "Unable to find cdb.exe. Install the Windows Debugging Tools or pass -DebuggerCommand." } function Resolve-ExecutablePath { param( [string]$Requested, [string]$Preset, [string]$Config ) if ($Requested.Length -gt 0) { return (Resolve-Path -LiteralPath $Requested).Path } $candidate = Join-Path -Path "out/build/$Preset/$Config" -ChildPath "PanoPainter.exe" if (Test-Path -LiteralPath $candidate) { return (Resolve-Path -LiteralPath $candidate).Path } throw "Unable to find PanoPainter.exe at '$candidate'. Pass -Executable to override." } function New-DebuggerCommandFile { param( [string]$Path, [bool]$BreakOnFirstChanceAccessViolation ) $lines = @() if ($BreakOnFirstChanceAccessViolation) { $lines += 'sxe -c ".echo ==== FIRST CHANCE AV ====; .ecxr; kb; kv; q" av' } $lines += "g" Set-Content -LiteralPath $Path -Value $lines } $cdb = Resolve-CdbPath $exe = Resolve-ExecutablePath -Requested $Executable -Preset $BuildPreset -Config $Configuration New-Item -ItemType Directory -Path $LogDir -Force | Out-Null $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" $commandFile = Join-Path -Path $LogDir -ChildPath "$timestamp-cdb.cmd" $logPath = Join-Path -Path $LogDir -ChildPath "$timestamp-cdb.log" New-DebuggerCommandFile -Path $commandFile -BreakOnFirstChanceAccessViolation:$BreakOnFirstChanceAccessViolation $process = Start-Process -FilePath $cdb -ArgumentList @( "-lines", "-logo", $logPath, "-cf", $commandFile, $exe ) -PassThru Start-Sleep -Seconds $StartupSmokeSeconds $app = Get-Process PanoPainter -ErrorAction SilentlyContinue $debugger = Get-Process cdb -ErrorAction SilentlyContinue | Where-Object { $_.Id -eq $process.Id } $summary = [ordered]@{ debugger = $cdb executable = $exe commandFile = $commandFile log = $logPath smokeSeconds = $StartupSmokeSeconds breakOnFirstChanceAccessViolation = [bool]$BreakOnFirstChanceAccessViolation debuggerRunning = [bool]$debugger appRunning = [bool]$app appResponding = if ($app) { [bool]$app.Responding } else { $false } mainWindowTitle = if ($app) { $app.MainWindowTitle } else { "" } } $summary | ConvertTo-Json -Compress if (-not $LeaveRunning) { if ($app) { Stop-Process -Id $app.Id -Force } if ($debugger) { Stop-Process -Id $debugger.Id -Force } }