You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mcsat: avoid eval_in_model longjmp on unmapped uninterpreted blasted leaf
Fixes the windows-latest|release|--enable-thread-safety --enable-mcsat
failure in tests/api/mcsat_tuples.c::test_partial_tuple_model_no_keep_subst.
Root cause (confirmed by the unbuffered Windows CI trace):
In preprocessor_build_tuple_model, when reconstructing the value of a
tuple-blasted atom, we call model_get_term_value() on each blasted
leaf. With keep_subst=0 the model has no alias table
(model->has_alias == 0), so eval_uninterpreted -- invoked transitively
on an *unmapped* uninterpreted leaf -- raises MDL_EVAL_UNKNOWN_TERM via
longjmp() to the setjmp() inside eval_in_model().
That longjmp path returns cleanly on macOS/Linux, but on MinGW x86_64
under -O3 -fomit-frame-pointer with THREAD_SAFE (TLS) enabled it
crashes inside the unwind. setjmp/longjmp on mingw-w64 x86_64 is
implemented via SEH and is sensitive to omitted frame pointers and TLS
interactions; this configuration is exactly the one that breaks.
The crash is reproducible and Windows-only because only this test
exercises all three triggers simultaneously: keep_subst=0 (no alias
table), an *unmapped* tuple-blasted leaf (the second component of the
unconstrained tuple x is never assigned during search), and that leaf
being an UNINTERPRETED_TERM (never substituted away by an equality).
Captured Windows CI trace (excerpt, before this fix):
[mcsat_tuples] START test_partial_tuple_model_no_keep_subst
[pp_build_model] enter, has_alias=0, eqs=1
...
[pp_build_tuple] i=0 atom=774 tau=21
[pp_build_tuple] n_leaves=2
[pp_build_tuple] j=0 leaf=780
[pp_build_tuple] model_get_term_value -> 2 <- mapped, fine
[pp_build_tuple] j=1 leaf=782 <- unmapped uninterp
<crash inside model_get_term_value>
Fix:
In the per-leaf loop of preprocessor_build_tuple_model, first try the
direct lookup model_find_term_value(). Only fall through to
model_get_term_value() (which can invoke eval_in_model) when there is
either an alias table to consult or the leaf is not an uninterpreted
term -- i.e., when the evaluator can plausibly produce a value. For
the remaining case (no alias + unmapped + uninterpreted), v stays at
null_value (< 0) and the existing fallback path mints a fresh default
via vtbl_make_object(leaf_tau), which is sound: an unmapped
uninterpreted leaf is unconstrained, so any value of the right type
preserves model correctness.
This avoids the longjmp/SEH unwind path entirely on the only execution
path where it could fire, fixing the Windows crash without changing
semantics on Linux/macOS.
The accompanying revert of TEMP-DIAG stderr prints (in preprocessor.c
and tests/api/mcsat_tuples.c) removes the now-unneeded instrumentation
that pinned the bug.
0 commit comments