Skip to content

Commit fd2375a

Browse files
Ben HillisCopilot
andcommitted
Add /attachdebugger option to automatically launch WinDbgX for test debugging
When /attachdebugger is passed to test.bat, run-tests.ps1 now: - Starts te.exe with /waitfordebugger in the background - Polls for the TE.ProcessHost.exe child process via WMI - Launches WinDbgX attached directly to the test host PID - With /inproc, attaches to TE.exe itself instead This replaces the manual workflow of running /waitfordebugger, reading the PID from the output, and launching WinDbgX separately. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f8e579a commit fd2375a

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

.github/copilot-instructions.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ Test execution:
9292
- **Requires Administrator privileges** - test.bat will fail without admin rights
9393

9494
Test debugging:
95-
- Wait for debugger: `/waitfordebugger`
95+
- Attach WinDbgX automatically: `/attachdebugger`
96+
- Wait for debugger (manual attach): `/waitfordebugger`
9697
- Break on failure: `/breakonfailure`
9798
- Run in-process: `/inproc`
9899

doc/docs/dev-loop.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ bin\x64\debug\test.bat /name:*UnitTest* -f
9696

9797
See [debugging](debugging.md) for general debugging instructions.
9898

99-
To attach a debugger to the unit test process, use: `/waitfordebugger` when calling `test.bat`.
99+
To automatically attach WinDbgX to the unit test process, use: `/attachdebugger` when calling `test.bat`.
100+
To wait for a debugger to be manually attached, use: `/waitfordebugger`.
100101
Use `/breakonfailure` to automatically break on the first test failure.
101102

102103
## Tips and tricks

test/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ Executing tests with TAEF is done by invoking the `TE.exe` binary:
1212
2. Navigate to the subdirectory containing the built test binaries (`bin/<X64|Arm64>/<Debug|Release>/`)
1313
3. Execute the binaries via invoking TE and passing the test dll/s as arguments: `TE.exe test1.dll test2.dll test3.dll`
1414

15+
## test.bat Options
16+
17+
The following options are handled by `test.bat` / `run-tests.ps1` before invoking TE.exe:
18+
19+
### **/attachdebugger**
20+
21+
Automatically launches WinDbgX and attaches it to the test host process. Requires [WinDbg](https://aka.ms/windbg) to be installed (`winget install Microsoft.WinDbg`). Under the hood it passes `/waitfordebugger` to TE.exe, finds the `TE.ProcessHost.exe` child process, and attaches WinDbgX to it. When combined with `/inproc`, WinDbgX attaches to `TE.exe` directly instead.
22+
23+
`test.bat /attachdebugger /name:*MyTest*`
24+
1525
## Useful **TE.exe** Command Line Parameters for Debugging/Executing Tests
1626

1727
Command Line parameters are passed to `TE.exe` after supplying the target `.dll`:

tools/test/run-tests.ps1

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,52 @@ if ($Fast)
4545
$SetupScript = $null
4646
}
4747

48-
te.exe $TestDllPath /p:SetupScript=$SetupScript /p:Version=$Version /p:DistroPath=$DistroPath /p:Package=$Package /p:UnitTestsPath=$UnitTestsPath /p:PullRequest=$PullRequest /p:AllowUnsigned=1 @TeArgs
48+
# Handle /attachdebugger: verify WinDbgX is available, then add /waitfordebugger so we can find and attach to the test host.
49+
$AttachDebugger = $false
50+
if ($TeArgs -and ($TeArgs -icontains '/attachdebugger'))
51+
{
52+
$TeArgs = @($TeArgs | Where-Object { $_ -ine '/attachdebugger' })
53+
if (Get-Command "WinDbgX.exe" -ErrorAction SilentlyContinue)
54+
{
55+
$AttachDebugger = $true
56+
$TeArgs += '/waitfordebugger'
57+
}
58+
else
59+
{
60+
Write-Warning "/attachdebugger was requested, but WinDbgX.exe was not found. Continuing without debugger."
61+
}
62+
}
4963

50-
if (!$?)
64+
$teArgList = @($TestDllPath, "/p:SetupScript=$SetupScript", "/p:Version=$Version", "/p:DistroPath=$DistroPath",
65+
"/p:Package=$Package", "/p:UnitTestsPath=$UnitTestsPath", "/p:PullRequest=$PullRequest", "/p:AllowUnsigned=1") + $TeArgs
66+
$teProcess = Start-Process -FilePath "te.exe" -ArgumentList $teArgList -PassThru -NoNewWindow
67+
68+
if ($AttachDebugger)
5169
{
52-
exit 1
53-
}
70+
$targetPid = if ($TeArgs -icontains '/inproc') { $teProcess.Id } else { $null }
71+
72+
if (-not $targetPid)
73+
{
74+
for ($i = 0; $i -lt 120 -and -not $teProcess.HasExited; $i++)
75+
{
76+
Start-Sleep -Milliseconds 500
77+
$child = Get-CimInstance Win32_Process -Filter "ParentProcessId = $($teProcess.Id) AND Name = 'TE.ProcessHost.exe'" -ErrorAction SilentlyContinue
78+
if ($child) { $targetPid = $child[0].ProcessId; break }
79+
}
80+
}
81+
82+
if ($targetPid)
83+
{
84+
$targetName = if ($targetPid -eq $teProcess.Id) { "TE.exe" } else { "TE.ProcessHost.exe" }
85+
Write-Host "Launching WinDbgX attached to $targetName (PID: $targetPid)..."
86+
Start-Process "WinDbgX.exe" -ArgumentList "-p $targetPid"
87+
}
88+
else
89+
{
90+
Write-Warning "Could not find TE.ProcessHost.exe within 60 seconds."
91+
Write-Host "Attach a debugger manually to TE.exe (PID: $($teProcess.Id))."
92+
}
93+
}
94+
95+
$teProcess | Wait-Process
96+
if ($teProcess.ExitCode -ne 0) { exit 1 }

0 commit comments

Comments
 (0)