Fix wrong iterator variable in InterpDropKeep ref tracking#2702
Merged
Conversation
In the "find dropped refs" loop of the InterpDropKeep handler, the condition checked `*iter` (the final position of the previous loop's iterator) instead of `*drop_iter` (the current loop's iterator). Since `iter` is not advanced in this loop, the condition was loop-invariant: it either always broke on the first iteration or never broke at all. This caused stale ref indices from the dropped value range to remain in `refs_`, which could lead to out-of-bounds access during garbage collection in Thread::Mark().
sbc100
approved these changes
Feb 25, 2026
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.
Summary
InterpDropKeephandler insrc/interp/interp.ccwhere the "find dropped refs" loop checked*iterinstead of*drop_iterProblem
In the
InterpDropKeepopcode handler, after shifting kept refs down, a second loop scans for refs that fall in the dropped value range so they can be erased. However, the loop condition on line 1687 dereferencediter(the end position of the previous loop) rather thandrop_iter(the current loop's iterator).Because
iteris never advanced in the second loop, the condition is loop-invariant: it either breaks immediately on the first iteration or never breaks at all. This means refs pointing into the dropped range may not be properly identified and erased fromrefs_, leaving stale indices that can cause out-of-bounds access whenThread::Mark()walksrefs_during garbage collection.Fix
Change
*iterto*drop_iteron the condition line so the loop correctly inspects each candidate ref index.Test plan
cmake --build build --target wabt-unittests)drop_iteris the intended loop variable