Fix intermittent key.core.testgen failures from SMT symbol-map race#3862
Merged
Conversation
The SMT symbol tables in SMTTermMultOp (and mirrored in SMTTermBinOp) were lazily initialized by publishing an empty map to the static field and only then populating it. Under concurrent SMT solver threads another thread could observe a half-built map and fail translation with a spurious "Unknown operator: EQUALS". Build the tables eagerly and publish them as immutable maps so no partial-initialization window exists. Also harden the related solver infrastructure: - VersionChecker: drop the racy BufferedReader.ready() check that intermittently reported "no version" under load; wait for the process to finish, then read; raise the timeout to 10s; return null instead of throwing on error. - SolverTypeImplementation: compare versions numerically instead of lexicographically (the old comparison rejected Z3 4.10+ against the configured minimum "Z3 version 4.4.1"). - TestCommons: skip via a JUnit assumption instead of silently passing when the solver is not installed/usable; genuine solver errors still fail. - tests.yml: pin setup-smt to z3Version 4.13.0 for reproducible CI. Created with AI tooling support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intended Change
key.core.testgenhas been failing intermittently in CI for the last few weeks(e.g. run 28220166551). All ~13 failures (
TestCE.*withSolverException,TestcaseGenerationE2ETest.arrayUtil) trace to a single root cause:RuntimeException: Unknown operator: EQUALS … intSym.size=18 bvSym.size=34raised during SMT term translation.
Root cause: the static SMT symbol tables in
SMTTermMultOp(mirrored inSMTTermBinOp) were lazily initialised by publishing an empty map to thestatic field and only then populating it
(
bvSymbols = new HashMap<>(); bvSymbols.put(...)), with non-volatile,unsynchronised fields. With concurrent SMT solver threads, one thread can
observe a half-built map and miss
EQUALS(which both maps actually contain),producing the spurious error — a timing-dependent, intermittent failure.
This PR fixes the race and hardens the surrounding solver infrastructure:
SMTTermMultOp/SMTTermBinOp: build the symbol tables eagerly andpublish them as immutable maps (
Map.copyOf) inprivate static finalfields, removing the lazy-init window entirely.
VersionChecker: the version probe gated onBufferedReader.ready(),which returns
falsewhenever the solver's output is not yet buffered (arace under load) and then reported "no version". It now waits for the process
to terminate before reading, raises the timeout to 10s, and returns
nullonerror instead of throwing.
SolverTypeImplementation: version support is now compared numericallyrather than lexicographically (the old comparison sorted e.g.
4.13.0beforethe configured minimum
Z3 version 4.4.1).TestCommons: when the solver is not installed/usable, the test now skipsvia a JUnit assumption instead of silently returning a passing result. Genuine
solver/translation errors are deliberately still surfaced as failures.
tests.yml: pinsetup-smttoz3Version: 4.13.0so CI is reproducible.Type of pull request
Ensuring quality
:key.core.testgen:testforTestCEand
TestcaseGenerationE2ETestlocally with Z3 4.15.4 — all pass (previously13 failed);
key.corecompiles andspotlessApplyreports no changes.are now built once eagerly rather than lazily, so there is no per-call cost.
Additional information and contact(s)
PR created with AI tooling support.
The contributions within this pull request are licensed under GPLv2 (only) for inclusion in KeY.