mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-09 03:29:43 -10:00
CI: enforce UBSan strict on ASan+UBSan workflow after clean baseline
Follow-up tob9777c8(the ASan+UBSan workflow). Run #1 of the new job came back clean: zero distinct UBSan diagnostics across the --help and --features smoke invocations. https://github.com/libretro/RetroArch/actions/runs/25056073385 * .github/workflows/Linux-asan-ubsan.yml - Flip UBSAN_OPTIONS=halt_on_error=0 to halt_on_error=1 in both smoke steps. A future change that introduces signed-overflow / alignment / shift-too-large UB along the option-parsing or print paths will now fail the run instead of being silently logged in a discovery summary. - Add a parallel grep -q "runtime error:" check after each timeout invocation so the failure is visible at exit code level even if a future sanitizer release changes the default abort semantics, mirroring the existing "AddressSanitizer:" check. - Drop the "Summarize UBSan baseline" step. Its job was to surface diagnostics during the discovery phase; with strict enforcement above it any non-zero count would have already aborted the run, so the summary is dead weight that suggested the workflow was still in soft-fail mode. - Step name updates: "ASan strict, UBSan soft-fail" -> "ASan + UBSan strict" on both smoke runs. Honest scoping note unchanged fromb9777c8: --help and --features both exit(0) directly without going through the normal shutdown path, so this enforces UBSan-cleanliness only for libc init / main / frontend bootstrap / option parsing / the print functions. Audio resampling, color math, parsers, and full-lifecycle cleanup still aren't covered. The follow-up step running with --max-frames=N against a noop core (deferred fromb9777c8) will extend coverage, and that step's first run will start in soft-fail mode the same way this one did.
This commit is contained in:
1 parent
60c7e39710
commit
70f24be5a5
1 file changed
+26
-30
@@ -85,7 +85,7 @@ jobs:
|
||||
test -x retroarch
|
||||
file retroarch
|
||||
|
||||
- name: Smoke run --help (ASan strict, UBSan soft-fail)
|
||||
- name: Smoke run --help (ASan + UBSan strict)
|
||||
# `--help` exits cleanly via exit(0) after printing the usage
|
||||
# banner. Coverage scope: libc init, main(), frontend
|
||||
# driver bootstrap, argv duplication, the getopt walk over
|
||||
@@ -93,13 +93,17 @@ jobs:
|
||||
# Doesn't reach into core loading / video init / cleanup-on-
|
||||
# shutdown -- a follow-up step running with --max-frames=N
|
||||
# against a noop core will extend coverage to the full
|
||||
# lifecycle. ASan runs in abort-on-error mode so any heap
|
||||
# corruption fails the job; UBSan reports stacktraces but
|
||||
# does not fail (first iteration -- we want to see the
|
||||
# baseline before deciding which UBSan classes to enforce).
|
||||
# lifecycle. ASan and UBSan both run in halt-on-error mode:
|
||||
# the first run of this workflow (Apr 28 2026, run #1)
|
||||
# reported zero distinct UBSan diagnostics across both
|
||||
# smoke invocations, so the baseline for these two surfaces
|
||||
# is clean and we enforce it. If a future change introduces
|
||||
# signed-overflow / alignment / shift-too-large UB along
|
||||
# the option-parsing or print paths, this step will fail
|
||||
# and the diagnostic line will be in the captured stderr.
|
||||
env:
|
||||
ASAN_OPTIONS: abort_on_error=1:detect_leaks=0:print_stacktrace=1:strict_string_checks=1
|
||||
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=0
|
||||
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
|
||||
# Avoid noise from libGL / Mesa / Wayland symbol-resolution
|
||||
# leaks at process shutdown; those are not RetroArch bugs.
|
||||
LSAN_OPTIONS: exitcode=0
|
||||
@@ -113,14 +117,21 @@ jobs:
|
||||
cat /tmp/help.err
|
||||
# ASan abort_on_error sends the process to exit code 1 + a
|
||||
# SUMMARY: line on stderr. Treat any "AddressSanitizer:"
|
||||
# marker as fatal regardless of exit code.
|
||||
# or UBSan "runtime error:" marker as fatal regardless of
|
||||
# exit code -- belt-and-suspenders to the runtime options
|
||||
# in case a future sanitizer release changes its default
|
||||
# exit semantics.
|
||||
if grep -q "AddressSanitizer:" /tmp/help.err; then
|
||||
echo "[FAIL] AddressSanitizer reported a finding"
|
||||
exit 1
|
||||
fi
|
||||
if grep -q "runtime error:" /tmp/help.err; then
|
||||
echo "[FAIL] UBSan reported a finding"
|
||||
exit 1
|
||||
fi
|
||||
echo "[pass] retroarch --help under ASan+UBSan"
|
||||
|
||||
- name: Smoke run --features (ASan strict, UBSan soft-fail)
|
||||
- name: Smoke run --features (ASan + UBSan strict)
|
||||
# `--features` exits cleanly via exit(0) after printing the
|
||||
# compile-time feature list. Coverage scope is the same as
|
||||
# --help (libc init / main / frontend bootstrap / arg parse)
|
||||
@@ -130,10 +141,11 @@ jobs:
|
||||
# such walk reads pointers into a static-string table -- low
|
||||
# corruption surface but a useful sanity check that the link-
|
||||
# time feature flags resolve consistently. Doesn't reach
|
||||
# core loading or cleanup-on-shutdown.
|
||||
# core loading or cleanup-on-shutdown. Like the --help step
|
||||
# this enforces UBSan strict because the baseline is clean.
|
||||
env:
|
||||
ASAN_OPTIONS: abort_on_error=1:detect_leaks=0:print_stacktrace=1:strict_string_checks=1
|
||||
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=0
|
||||
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
|
||||
LSAN_OPTIONS: exitcode=0
|
||||
run: |
|
||||
set -eu
|
||||
@@ -147,24 +159,8 @@ jobs:
|
||||
echo "[FAIL] AddressSanitizer reported a finding"
|
||||
exit 1
|
||||
fi
|
||||
echo "[pass] retroarch --features under ASan+UBSan"
|
||||
|
||||
- name: Summarize UBSan baseline
|
||||
# Both runtime steps are non-fatal on UBSan diagnostics. This
|
||||
# step prints a count of distinct UBSan messages observed so
|
||||
# follow-up patches have a numerical target to drive to zero.
|
||||
# If this step ever shows zero, flip
|
||||
# UBSAN_OPTIONS=halt_on_error=1 in the runtime steps above to
|
||||
# enforce the clean baseline.
|
||||
if: always()
|
||||
run: |
|
||||
set +e
|
||||
ub_count=$( {
|
||||
grep -h "runtime error:" /tmp/help.err /tmp/features.err 2>/dev/null
|
||||
} | sort -u | wc -l)
|
||||
echo "UBSan distinct diagnostics: ${ub_count}"
|
||||
if [ "${ub_count}" != "0" ]; then
|
||||
echo "=== unique UBSan diagnostics ==="
|
||||
grep -h "runtime error:" /tmp/help.err /tmp/features.err 2>/dev/null \
|
||||
| sort -u
|
||||
if grep -q "runtime error:" /tmp/features.err; then
|
||||
echo "[FAIL] UBSan reported a finding"
|
||||
exit 1
|
||||
fi
|
||||
echo "[pass] retroarch --features under ASan+UBSan"
|
||||
Reference in new issue
Block a user