Skip to content

Commit aa0db3c

Browse files
authored
Merge pull request #3 from awakecoding/awakecoding/dump-support
Add process dump smoke and Windows package workflows
2 parents e9c6fc7 + b2c4acc commit aa0db3c

16 files changed

Lines changed: 1045 additions & 70 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
name: Windows packages
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
jobs:
9+
package:
10+
name: Package ${{ matrix.label }}
11+
runs-on: windows-latest
12+
timeout-minutes: 60
13+
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
include:
18+
- label: windows-x64
19+
rust_target: x86_64-pc-windows-msvc
20+
nuget_arch: amd64
21+
vcvars_arch: x64
22+
artifact: windbg-tool-windows-x64
23+
can_run: true
24+
- label: windows-arm64
25+
rust_target: aarch64-pc-windows-msvc
26+
nuget_arch: arm64
27+
vcvars_arch: x64_arm64
28+
artifact: windbg-tool-windows-arm64
29+
can_run: false
30+
31+
env:
32+
CARGO_TERM_COLOR: always
33+
RUSTFLAGS: -C target-feature=+crt-static
34+
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@v5
38+
39+
- name: Select stable Rust
40+
shell: pwsh
41+
run: |
42+
rustup default stable
43+
rustup target add ${{ matrix.rust_target }}
44+
45+
- name: Restore debugger dependencies
46+
shell: pwsh
47+
run: cargo xtask deps --arch ${{ matrix.nuget_arch }}
48+
49+
- name: Ensure ARM64 MSVC toolset
50+
if: matrix.nuget_arch == 'arm64'
51+
shell: pwsh
52+
run: |
53+
$ErrorActionPreference = 'Stop'
54+
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
55+
$installer = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vs_installer.exe'
56+
if (-not (Test-Path $vswhere)) {
57+
throw "vswhere.exe was not found at $vswhere"
58+
}
59+
if (-not (Test-Path $installer)) {
60+
throw "vs_installer.exe was not found at $installer"
61+
}
62+
$installationPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
63+
if (-not $installationPath) {
64+
throw 'Could not find a Visual Studio installation with the MSVC x64 toolset'
65+
}
66+
& $installer modify `
67+
--installPath $installationPath `
68+
--add Microsoft.VisualStudio.Component.VC.Tools.ARM64 `
69+
--quiet `
70+
--norestart `
71+
--nocache `
72+
--wait
73+
if (($LASTEXITCODE -ne 0) -and ($LASTEXITCODE -ne 3010)) {
74+
exit $LASTEXITCODE
75+
}
76+
77+
- name: Build native bridge
78+
shell: pwsh
79+
run: |
80+
$ErrorActionPreference = 'Stop'
81+
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
82+
$installationPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
83+
if (-not $installationPath) {
84+
throw 'Could not find a Visual Studio installation with the MSVC x64 toolset'
85+
}
86+
$vcvars = Join-Path $installationPath 'VC\Auxiliary\Build\vcvarsall.bat'
87+
cmd /c "`"$vcvars`" ${{ matrix.vcvars_arch }} && cargo xtask native-build --arch ${{ matrix.nuget_arch }} --static-crt"
88+
89+
- name: Build windbg-tool
90+
shell: pwsh
91+
run: |
92+
$ErrorActionPreference = 'Stop'
93+
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
94+
$installationPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
95+
if (-not $installationPath) {
96+
throw 'Could not find a Visual Studio installation with the MSVC x64 toolset'
97+
}
98+
$vcvars = Join-Path $installationPath 'VC\Auxiliary\Build\vcvarsall.bat'
99+
cmd /c "`"$vcvars`" ${{ matrix.vcvars_arch }} && cargo build -p windbg-tool --release --target ${{ matrix.rust_target }}"
100+
101+
- name: Package runtime files
102+
shell: pwsh
103+
run: |
104+
cargo xtask package `
105+
--arch ${{ matrix.nuget_arch }} `
106+
--target ${{ matrix.rust_target }} `
107+
--profile release `
108+
--out "target\package\${{ matrix.artifact }}"
109+
110+
- name: Validate package and create ZIP
111+
shell: pwsh
112+
run: |
113+
$ErrorActionPreference = 'Stop'
114+
115+
$packageDir = Join-Path $PWD 'target\package\${{ matrix.artifact }}'
116+
$zipPath = Join-Path $PWD 'target\package\${{ matrix.artifact }}.zip'
117+
$requiredFiles = @(
118+
'windbg-tool.exe',
119+
'ttd_replay_bridge.dll',
120+
'TTDReplay.dll',
121+
'TTDReplayCPU.dll',
122+
'dbgeng.dll',
123+
'dbgcore.dll',
124+
'dbghelp.dll',
125+
'dbgmodel.dll',
126+
'msdia140.dll',
127+
'symsrv.dll',
128+
'srcsrv.dll'
129+
)
130+
131+
foreach ($file in $requiredFiles) {
132+
$path = Join-Path $packageDir $file
133+
if (-not (Test-Path $path)) {
134+
throw "Package is missing required file: $file"
135+
}
136+
}
137+
138+
if ('${{ matrix.can_run }}' -eq 'true') {
139+
Push-Location $packageDir
140+
try {
141+
& '.\windbg-tool.exe' discover | Out-Null
142+
}
143+
finally {
144+
Pop-Location
145+
}
146+
}
147+
148+
if (Test-Path $zipPath) {
149+
Remove-Item $zipPath -Force
150+
}
151+
Compress-Archive -Path (Join-Path $packageDir '*') -DestinationPath $zipPath -Force
152+
153+
Add-Type -AssemblyName System.IO.Compression.FileSystem
154+
$zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
155+
try {
156+
$entries = @($zip.Entries | ForEach-Object { $_.FullName.Replace('/', '\') })
157+
foreach ($file in $requiredFiles) {
158+
if ($entries -notcontains $file) {
159+
throw "ZIP is missing required file: $file"
160+
}
161+
}
162+
}
163+
finally {
164+
$zip.Dispose()
165+
}
166+
167+
- name: Upload package
168+
uses: actions/upload-artifact@v6
169+
with:
170+
name: ${{ matrix.artifact }}
171+
path: target\package\${{ matrix.artifact }}.zip
172+
if-no-files-found: error

.github/workflows/smoke-tests.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: Smoke tests
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
jobs:
9+
dump-smoke:
10+
name: Process dump smoke test
11+
runs-on: windows-latest
12+
timeout-minutes: 30
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v5
17+
18+
- name: Select stable Rust
19+
shell: pwsh
20+
run: rustup default stable
21+
22+
- name: Restore debugger dependencies
23+
shell: pwsh
24+
run: cargo xtask deps
25+
26+
- name: Build windbg-tool
27+
shell: pwsh
28+
run: cargo build -p windbg-tool
29+
30+
- name: Create and inspect ping dump
31+
shell: pwsh
32+
timeout-minutes: 10
33+
run: |
34+
$ErrorActionPreference = 'Stop'
35+
36+
$tool = Join-Path $PWD 'target\debug\windbg-tool.exe'
37+
$dumpDir = Join-Path $env:RUNNER_TEMP 'windbg-tool-smoke'
38+
New-Item -ItemType Directory -Path $dumpDir -Force | Out-Null
39+
$dumpPath = Join-Path $dumpDir 'ping.dmp'
40+
Remove-Item -Path $dumpPath -Force -ErrorAction SilentlyContinue
41+
42+
Write-Host 'Launching ping.exe'
43+
$ping = Start-Process `
44+
-FilePath 'C:\Windows\System32\ping.exe' `
45+
-ArgumentList @('127.0.0.1', '-n', '10') `
46+
-PassThru
47+
48+
try {
49+
Start-Sleep -Seconds 1
50+
51+
Write-Host 'Creating process dump'
52+
$created = & $tool dump create `
53+
--process-id $ping.Id `
54+
--output $dumpPath `
55+
--kind mini `
56+
--overwrite | Tee-Object -Variable createOutput
57+
$createOutput | ConvertFrom-Json | Out-Null
58+
59+
if (-not (Test-Path $dumpPath)) {
60+
throw "Expected dump file was not created: $dumpPath"
61+
}
62+
63+
$dumpFile = Get-Item $dumpPath
64+
if ($dumpFile.Length -le 0) {
65+
throw "Dump file is empty: $dumpPath"
66+
}
67+
}
68+
finally {
69+
if (-not $ping.HasExited) {
70+
Write-Host 'Terminating ping.exe'
71+
Stop-Process -Id $ping.Id -Force
72+
$ping.WaitForExit()
73+
}
74+
}
75+
76+
Write-Host 'Opening and inspecting dump'
77+
$inspection = & $tool dump inspect $dumpPath --max-frames 8 | ConvertFrom-Json
78+
if ($inspection.target.kind -ne 'dump') {
79+
throw "Expected dump target kind, got '$($inspection.target.kind)'"
80+
}
81+
82+
Write-Host 'Checking modules'
83+
$pingModule = $inspection.modules | Where-Object {
84+
($_.module_name -like '*ping*') -or
85+
($_.image_name -like '*ping.exe*') -or
86+
($_.loaded_image_name -like '*ping.exe*')
87+
} | Select-Object -First 1
88+
if (-not $pingModule) {
89+
throw "Expected loaded modules to include ping.exe"
90+
}
91+
92+
Write-Host 'Checking threads'
93+
if (-not $inspection.threads -or $inspection.threads.Count -lt 1) {
94+
throw "Expected at least one thread in the dump"
95+
}
96+
97+
Write-Host 'Checking registers'
98+
if (
99+
-not $inspection.registers.instruction_offset -and
100+
-not $inspection.registers.stack_offset -and
101+
-not $inspection.registers.frame_offset
102+
) {
103+
throw "Expected at least one current-thread register offset in the dump"
104+
}
105+
106+
Write-Host 'Checking stack'
107+
if (-not $inspection.frames -or $inspection.frames.Count -lt 1) {
108+
throw "Expected at least one stack frame in the dump"
109+
}
110+
111+
- name: Upload dump on failure
112+
if: failure()
113+
uses: actions/upload-artifact@v6
114+
with:
115+
name: ping-dump-smoke
116+
path: ${{ runner.temp }}\windbg-tool-smoke\ping.dmp
117+
if-no-files-found: ignore
118+
retention-days: 3

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ The built executable is:
4141
target\debug\windbg-tool.exe
4242
```
4343

44+
Release ZIP artifacts are built by the Windows packaging workflow. The local equivalent uses `cargo xtask deps --arch <amd64|arm64>`, `cargo xtask native-build --arch <amd64|arm64> --static-crt`, a release build for the matching MSVC Rust target, and `cargo xtask package --profile release`.
45+
4446
For deeper setup, test commands, runtime details, and workspace notes, see [the development guide](docs/development.md).
4547

4648
## CLI quick start
@@ -70,7 +72,7 @@ Representative command areas:
7072
- Discovery: `discover`, `recipes`, `tools`, `schema`
7173
- Session and replay: `open`, `load`, `sessions`, `info`, `position set`, `step`, `replay to`
7274
- Analysis: `symbols diagnose`, `disasm`, `memory dump`, `memory strings`, `memory chase`, `stack recover`, `stack backtrace`
73-
- Platform helpers: `remote explain`, `dbgeng server`, `live launch`, `windbg status`
75+
- Platform helpers: `remote explain`, `dbgeng server`, `live launch`, `dump create`, `dump inspect`, `windbg status`
7476

7577
For a fuller CLI walkthrough, output-shaping flags, and command map, see [the CLI guide](docs/cli.md).
7678

crates/windbg-dbgeng/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ serde.workspace = true
1111
[target.'cfg(windows)'.dependencies]
1212
windows = { workspace = true, features = [
1313
"Win32_Foundation",
14+
"Win32_Storage_FileSystem",
1415
"Win32_System_Diagnostics_Debug",
1516
"Win32_System_Diagnostics_Debug_Extensions",
17+
"Win32_System_Kernel",
1618
"Win32_System_Memory",
1719
"Win32_System_ProcessStatus",
1820
"Win32_System_SystemInformation",

0 commit comments

Comments
 (0)