Skip to content

Commit 50cfd92

Browse files
committed
Support crash dumps for e2e tests
1 parent ed311b4 commit 50cfd92

3 files changed

Lines changed: 86 additions & 20 deletions

File tree

.ado/jobs/e2e-test.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ jobs:
4646
platform: ${{ matrix.BuildPlatform }}
4747
configuration: Release
4848
buildEnvironment: ${{ config.buildEnvironment }}
49+
# Capture crash dumps for the E2E test app (packaged UWP) and
50+
# the Metro bundler. ProcDump-as-AeDebug does not reliably fire
51+
# for packaged apps; WER LocalDumps does.
52+
localDumpsExeNames:
53+
- RNTesterApp-Fabric
54+
- node
4955

5056
- pwsh: |
5157
Write-Host "##vso[task.setvariable variable=BuildLogDirectory]$(Build.BinariesDirectory)\${{ matrix.BuildPlatform }}\BuildLogs"
@@ -76,6 +82,30 @@ jobs:
7682
workingDirectory: packages/e2e-test-app-fabric
7783
timeoutInMinutes: 10 # Time to wait for this task to complete before the server kills it.
7884
85+
# On test failure, snapshot any lingering RNTesterApp-Fabric / node
86+
# processes before subsequent steps (or the agent) tear them down.
87+
# WER LocalDumps only fires on actual crashes; this catches hangs
88+
# (e.g. "Unable to enter correct text" timeouts) where the process
89+
# is alive but unresponsive.
90+
- pwsh: |
91+
$procDump = Join-Path "$(ProcDumpPath)" 'procdump64.exe'
92+
if (-not (Test-Path $procDump)) {
93+
Write-Host "ProcDump not found at $procDump; skipping live-process dump capture."
94+
exit 0
95+
}
96+
97+
$targets = @('RNTesterApp-Fabric', 'node')
98+
foreach ($name in $targets) {
99+
Get-Process -Name $name -ErrorAction SilentlyContinue | ForEach-Object {
100+
$dumpPath = Join-Path "$(CrashDumpRootPath)" ("hang_{0}_{1}.dmp" -f $name, $_.Id)
101+
Write-Host "Capturing full dump of $name (pid $($_.Id)) to $dumpPath"
102+
& $procDump -accepteula -ma $_.Id $dumpPath
103+
}
104+
}
105+
displayName: Capture dumps of surviving test processes
106+
condition: and(failed(), eq(variables.StartedFabricTests, 'true'))
107+
continueOnError: true
108+
79109
- script: npx jest --clearCache
80110
displayName: clear jest cache
81111
workingDirectory: packages/e2e-test-app-fabric

.ado/scripts/SetupLocalDumps.cmd

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,57 @@
11
@echo off
2-
REM SetupLocalDumps.cmd [ExecutableName] [DumpFolder]
3-
REM Ex: .\SetupLocalDumps.cmd RNTesterApp C:\WER\UserDumps
2+
REM SetupLocalDumps.cmd [ExecutableName] [DumpFolder] [DumpType] [DumpCount]
3+
REM Ex: .\SetupLocalDumps.cmd RNTesterApp-Fabric C:\WER\UserDumps
4+
REM Ex: .\SetupLocalDumps.cmd RNTesterApp-Fabric C:\WER\UserDumps 2 5
45
REM
5-
REM This script sets the registry so that, if an executable of the given name crashes, to
6-
REM prevent any automatic debugger from attaching, and instead save a full crash dump to
7-
REM the given folder.
6+
REM Configures Windows Error Reporting (WER) to save crash dumps for the named
7+
REM executable to the given folder. This is the supported mechanism for
8+
REM packaged/UWP apps where AeDebug-based JIT debuggers (e.g. ProcDump) are
9+
REM not reliably invoked.
10+
REM
11+
REM DumpType:
12+
REM 1 = Custom dump (uses CustomDumpFlags)
13+
REM 2 = Full dump (default)
14+
REM 3 = Mini dump
15+
REM
16+
REM DumpCount: max number of dumps to keep per exe (default 10)
817

9-
setlocal
18+
setlocal enableextensions
1019

11-
if "%1"=="" (
20+
if "%~1"=="" (
1221
@echo Must provide an executable name to set up local crash dumps
1322
exit /b 1
1423
)
15-
if "%2"=="" (
24+
if "%~2"=="" (
1625
@echo Must provide a writable folder to save local crash dumps
1726
exit /b 1
1827
)
1928

20-
set CRASHDUMPS_FOLDER=%2
21-
@echo Configuring registry to save "%1.exe" crash dumps to "%CRASHDUMPS_FOLDER%"...
22-
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\%1.exe" /v DumpFolder /t REG_EXPAND_SZ /d %CRASHDUMPS_FOLDER%
23-
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\%1.exe" /v DumpType /t REG_DWORD /d 2
24-
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\%1.exe" /v DumpCount /t REG_DWORD /d 3
25-
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\AutoExclusionList" /v %1.exe /t REG_DWORD /d 1
26-
if not exist %CRASHDUMPS_FOLDER% (
29+
set EXE_NAME=%~1
30+
set CRASHDUMPS_FOLDER=%~2
31+
set DUMP_TYPE=%~3
32+
set DUMP_COUNT=%~4
33+
if "%DUMP_TYPE%"=="" set DUMP_TYPE=2
34+
if "%DUMP_COUNT%"=="" set DUMP_COUNT=10
35+
36+
if not exist "%CRASHDUMPS_FOLDER%" (
2737
@echo Creating %CRASHDUMPS_FOLDER%
28-
md %CRASHDUMPS_FOLDER%
38+
md "%CRASHDUMPS_FOLDER%"
2939
)
3040

41+
set REG_KEY=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\%EXE_NAME%.exe
42+
@echo Configuring WER to save "%EXE_NAME%.exe" crash dumps (DumpType=%DUMP_TYPE%, DumpCount=%DUMP_COUNT%) to "%CRASHDUMPS_FOLDER%"...
43+
reg add "%REG_KEY%" /v DumpFolder /t REG_EXPAND_SZ /d "%CRASHDUMPS_FOLDER%" /f
44+
reg add "%REG_KEY%" /v DumpType /t REG_DWORD /d %DUMP_TYPE% /f
45+
reg add "%REG_KEY%" /v DumpCount /t REG_DWORD /d %DUMP_COUNT% /f
46+
47+
REM Prevent the AeDebug post-mortem debugger from being invoked for this
48+
REM executable so that WER LocalDumps gets first crack and writes to our folder.
49+
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\AutoExclusionList" /v %EXE_NAME%.exe /t REG_DWORD /d 1 /f
50+
3151
@echo Registry configuration:
32-
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\%1.exe" /s
33-
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\AutoExclusionList"
52+
reg query "%REG_KEY%" /s
53+
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\AutoExclusionList" /v %EXE_NAME%.exe
3454

3555
endlocal
3656

37-
exit /b %ERRORLEVEL%
57+
exit /b %ERRORLEVEL%

.ado/templates/prepare-build-env.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ parameters:
2222
# - PullRequest
2323
# - Continuous
2424
# - Publish
25+
- name: localDumpsExeNames
26+
type: object
27+
default: []
28+
# List of executable base names (without .exe) to register with WER LocalDumps,
29+
# so that crashes in those processes write a dump to $(CrashDumpRootPath).
30+
# Required for packaged/UWP apps where ProcDump-as-AeDebug is not reliably
31+
# invoked. Example: ['RNTesterApp-Fabric', 'Playground'].
2532

2633
steps:
2734
# The commit tag in the nuspec requires that we use at least nuget 5.8 (because things break with nuget versions before and Vs 16.8 or later)
@@ -59,4 +66,13 @@ steps:
5966
- pwsh: |
6067
& $(Build.SourcesDirectory)\.ado\scripts\RunProcDump.ps1 -ProcDumpArgs @("-mm", "-i", "$(CrashDumpRootPath)") -ProcDumpInstallPath "$(ProcDumpPath)" -Verbose
6168
displayName: Setup ProcDump as AeDebug
62-
69+
70+
# Register WER LocalDumps for any executables the caller cares about.
71+
# This catches crashes in packaged/UWP apps (e.g. RNTesterApp-Fabric) that
72+
# the AeDebug-based ProcDump path does not reliably intercept. Dumps land
73+
# in $(CrashDumpRootPath), which is already wired to the crash-dump artifact
74+
# publisher in upload-build-logs.yml.
75+
- ${{ each exeName in parameters.localDumpsExeNames }}:
76+
- script: |
77+
call "$(Build.SourcesDirectory)\.ado\scripts\SetupLocalDumps.cmd" "${{ exeName }}" "$(CrashDumpRootPath)"
78+
displayName: Register WER LocalDumps for ${{ exeName }}.exe

0 commit comments

Comments
 (0)