Skip to content

Commit b2c8067

Browse files
committed
Capture full native-crash diagnostics from all CI test jobs
The previous CI failure on Windows uploaded only the *.dumpstream file (surefire's view), leaving us no way to see the JVM crash log, the native callstack, or which @test method was running when the abort fired. Linux had similar gaps. Fix both the JVM-side capture and the upload globs across all four test jobs. JVM side (pom.xml) - Add an explicit maven-surefire-plugin 3.5.4 entry (the same version Maven was auto-selecting in CI, pinned now so we do not drift independently of plugin-defaults bumps). - argLine: '@{argLine} -XX:ErrorFile=hs_err_pid%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=.' . @{argLine} interpolation preserves the jacoco runtime agent set by jacoco-maven-plugin:prepare-agent (must not break coverage); ErrorFile is workspace-relative so the JVM crash log lands next to the basedir, where the CI upload step already globs hs_err_pid*.log. - redirectTestOutputToFile=true so each test class's stdout/stderr (including the upstream server's I srv ... log lines, which are the only signal of which @test was last running before a crash) is captured to target/surefire-reports/<class>-output.txt. CI side (.github/workflows/publish.yml) - All four test jobs (linux-x86_64, macos-14-metal, macos-15-metal, macos-15-no-metal) expand their failure upload-artifact path globs to: hs_err_pid*.log *.hprof (heap dumps on OOM) core.* (linux only — already) target/surefire-reports/*.dump target/surefire-reports/*.dumpstream target/surefire-reports/*.txt (per-class summary + the new -output.txt capture) target/surefire-reports/TEST-*.xml - Windows test job gains an 'Enable WER LocalDumps for java.exe' step BEFORE 'Run tests'. Registers HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting \LocalDumps\java.exe with DumpFolder=workspace\dumps, DumpType=2 (MiniDumpWithFullMemory), DumpCount=5. This is the Windows analogue of Linux core dumps; without it a __fastfail / abort from the JNI layer leaves no native callstack at all. Windows upload path globs add dumps\*.dmp, *.hprof, *.txt, TEST-*.xml. Verified - mvn test -Dtest='ContentPartTest,MultimodalMessagesTest, CancellationTokenTest': 31 tests pass with the new argLine + redirectTestOutputToFile; jacoco coverage report still generated (52 classes analysed). @{argLine} requires the full 'mvn test' phase (jacoco prepare-agent runs first); 'mvn surefire:test' direct invocation breaks because @{...} is a phase-only late binding — CI uses the full phase, so unaffected.
1 parent f399a8c commit b2c8067

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,11 @@ jobs:
370370
name: error-log-macos-15-metal
371371
path: |
372372
${{ github.workspace }}/hs_err_pid*.log
373+
${{ github.workspace }}/*.hprof
373374
${{ github.workspace }}/target/surefire-reports/*.dump
374375
${{ github.workspace }}/target/surefire-reports/*.dumpstream
376+
${{ github.workspace }}/target/surefire-reports/*.txt
377+
${{ github.workspace }}/target/surefire-reports/TEST-*.xml
375378
if-no-files-found: warn
376379

377380
# ---------------------------------------------------------------------------
@@ -447,8 +450,11 @@ jobs:
447450
path: |
448451
${{ github.workspace }}/hs_err_pid*.log
449452
${{ github.workspace }}/core.*
453+
${{ github.workspace }}/*.hprof
450454
${{ github.workspace }}/target/surefire-reports/*.dump
451455
${{ github.workspace }}/target/surefire-reports/*.dumpstream
456+
${{ github.workspace }}/target/surefire-reports/*.txt
457+
${{ github.workspace }}/target/surefire-reports/TEST-*.xml
452458
if-no-files-found: warn
453459

454460
test-java-macos-arm64-metal:
@@ -508,8 +514,11 @@ jobs:
508514
name: error-log-macos-14-metal
509515
path: |
510516
${{ github.workspace }}/hs_err_pid*.log
517+
${{ github.workspace }}/*.hprof
511518
${{ github.workspace }}/target/surefire-reports/*.dump
512519
${{ github.workspace }}/target/surefire-reports/*.dumpstream
520+
${{ github.workspace }}/target/surefire-reports/*.txt
521+
${{ github.workspace }}/target/surefire-reports/TEST-*.xml
513522
if-no-files-found: warn
514523

515524
test-java-macos-arm64-no-metal:
@@ -569,8 +578,11 @@ jobs:
569578
name: error-log-macos-15-no-metal
570579
path: |
571580
${{ github.workspace }}/hs_err_pid*.log
581+
${{ github.workspace }}/*.hprof
572582
${{ github.workspace }}/target/surefire-reports/*.dump
573583
${{ github.workspace }}/target/surefire-reports/*.dumpstream
584+
${{ github.workspace }}/target/surefire-reports/*.txt
585+
${{ github.workspace }}/target/surefire-reports/TEST-*.xml
574586
if-no-files-found: warn
575587

576588
test-java-windows-x86_64:
@@ -617,6 +629,23 @@ jobs:
617629
- name: Memory before tests
618630
run: Get-CimInstance Win32_OperatingSystem | Select-Object FreePhysicalMemory,TotalVisibleMemorySize | Format-List
619631
shell: pwsh
632+
- name: Enable WER LocalDumps for java.exe
633+
# Windows Error Reporting writes minidumps when java.exe (or any other
634+
# registered process) crashes via __fastfail / abort / unhandled SEH.
635+
# We use it as the Windows analogue of Linux core dumps so that a JVM
636+
# crash inside the JNI layer leaves us a real native callstack instead
637+
# of just surefire's "VM terminated without saying goodbye" line.
638+
# DumpType=2 == MiniDumpWithFullMemory; the workspace dumps/ folder is
639+
# globbed by the failure-upload step below.
640+
shell: pwsh
641+
run: |
642+
$key = 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\java.exe'
643+
New-Item -Path $key -Force | Out-Null
644+
New-Item -Path "${{ github.workspace }}\dumps" -ItemType Directory -Force | Out-Null
645+
New-ItemProperty -Path $key -Name 'DumpFolder' -Value "${{ github.workspace }}\dumps" -PropertyType ExpandString -Force | Out-Null
646+
New-ItemProperty -Path $key -Name 'DumpType' -Value 2 -PropertyType DWord -Force | Out-Null
647+
New-ItemProperty -Path $key -Name 'DumpCount' -Value 5 -PropertyType DWord -Force | Out-Null
648+
Get-ItemProperty -Path $key | Format-List
620649
- name: Run tests
621650
run: |
622651
mvn --no-transfer-progress test `
@@ -633,8 +662,12 @@ jobs:
633662
name: windows-output
634663
path: |
635664
${{ github.workspace }}\hs_err_pid*.log
665+
${{ github.workspace }}\*.hprof
666+
${{ github.workspace }}\dumps\*.dmp
636667
${{ github.workspace }}\target\surefire-reports\*.dump
637668
${{ github.workspace }}\target\surefire-reports\*.dumpstream
669+
${{ github.workspace }}\target\surefire-reports\*.txt
670+
${{ github.workspace }}\target\surefire-reports\TEST-*.xml
638671
${{ github.workspace }}/src/main/resources/net/ladenthin/llama/**/*
639672
if-no-files-found: warn
640673

pom.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,35 @@ SPDX-License-Identifier: MIT
269269
</execution>
270270
</executions>
271271
</plugin>
272+
<plugin>
273+
<!--
274+
Surefire is configured here only to control native-crash diagnostics:
275+
- argLine inherits jacoco's @{argLine} (so the jacoco runtime agent stays
276+
attached) and appends -XX:ErrorFile so the JVM crash log (hs_err_pid<pid>.log)
277+
always lands in the project basedir, which is the same directory the CI
278+
upload-artifact globs (${{ github.workspace }}/hs_err_pid*.log).
279+
- HeapDumpOnOutOfMemoryError + HeapDumpPath catch OOMs that would otherwise
280+
just print a stack and exit.
281+
- The version is pinned to the same release Maven would otherwise auto-select
282+
(visible in CI error logs as 3.5.4), so we don't drift independently of
283+
Maven's plugin-defaults bump.
284+
-->
285+
<groupId>org.apache.maven.plugins</groupId>
286+
<artifactId>maven-surefire-plugin</artifactId>
287+
<version>3.5.4</version>
288+
<configuration>
289+
<argLine>@{argLine} -XX:ErrorFile=hs_err_pid%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=.</argLine>
290+
<!--
291+
Capture each test class's stdout/stderr into
292+
target/surefire-reports/<class>-output.txt. When a native crash
293+
takes down the forked JVM, this file is the ONLY record of
294+
which @Test method was last running (without it the surefire
295+
*.txt summary just says "VM terminated", which we already saw
296+
in CI without telling us which test was on fire).
297+
-->
298+
<redirectTestOutputToFile>true</redirectTestOutputToFile>
299+
</configuration>
300+
</plugin>
272301
</plugins>
273302
</build>
274303

0 commit comments

Comments
 (0)