Skip to content

jit: Don't resume a recycled context - #2454

Open
petermm wants to merge 1 commit into
atomvm:release-0.7from
petermm:fix/jit-context-reuse
Open

petermm wants to merge 1 commit into
atomvm:release-0.7from
petermm:fix/jit-context-reuse

Conversation

@petermm

@petermm petermm commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

jit_terminate_context() destroyed the dispatched context and then returned the context scheduler_run() picked next. scheduler_entry_point compares that context with the one it dispatched to decide whether the same context keeps running, and the generated return_if_not_equal_to_ctx comparison checks the value a primitive returns the same way. A spawn on another scheduler thread can reuse the just freed address, so the comparison succeeds for the new process: the dispatcher keeps the terminated process's module and continuation and resumes the new process there, with the new process's empty stack and its own cp. It surfaces as a stack pop in an unrelated module, typically socket:accept0/2, followed by "Context heap is corrupted, cannot find fragment with stack pointer".

Hand the next context to the dispatcher through JITState and return NULL from jit_terminate_context(), so neither comparison can mistake a recycled context for the dispatched one.

test_net_kernel ran 500 times on macOS arm64 with the JIT with no crash, no hang and no failure, against roughly one failure per 60 to 300 runs before. The exact signature in the CI log was not reproduced locally, before or after the change; the wrong-continuation symptom was.

Fixes: #2453

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

@petermm
petermm force-pushed the fix/jit-context-reuse branch from b19ede8 to c0c0380 Compare October 30, 2026 13:29
Comment thread src/libAtomVM/jit.h Resolved
@petermm
petermm force-pushed the fix/jit-context-reuse branch from c0c0380 to 809153d Compare October 31, 2026 08:37
Comment thread src/libAtomVM/opcodesswitch.h Resolved
jit_terminate_context() destroyed the dispatched context and then
returned the context scheduler_run() picked next. scheduler_entry_point
compares that context with the one it dispatched to decide whether the
same context keeps running, and the generated return_if_not_equal_to_ctx
comparison checks the value a primitive returns the same way. A spawn on
another scheduler thread can reuse the just freed address, so the
comparison succeeds for the new process: the dispatcher keeps the
terminated process's module and continuation and resumes the new process
there, with the new process's empty stack and its own cp. It surfaces as
a stack pop in an unrelated module, typically socket:accept0/2, followed
by "Context heap is corrupted, cannot find fragment with stack pointer".

Hand the next context to the dispatcher through JITState and return NULL
from jit_terminate_context(), so neither comparison can mistake a
recycled context for the dispatched one.

test_net_kernel ran 500 times on macOS arm64 with the JIT with no crash,
no hang and no failure, against roughly one failure per 60 to 300 runs
before. The exact signature in the CI log was not reproduced locally,
before or after the change; the wrong-continuation symptom was.

Fixes: atomvm#2453
Signed-off-by: Peter Madsen-Mygdal <petermm@gmail.com>
@petermm
petermm force-pushed the fix/jit-context-reuse branch from 809153d to 1f2767a Compare October 31, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants