Fix process_info that can hang waiting for reply #5078
Merged
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.
With multiple reusable receive markers, marker that is marked
to remove may be followed by process_info signal, which will
also be handled within the loop in erts_proc_sig_handle_incoming.
It is possible that process_info moves messages up to the next
non-message signal from the middle to inner queue. If there was a
receive marker at the very beginning of the middle queue, it
would set save pointer to sig_qs.cont, which will be overwritten
when linking middle queue head into inner queue. This would make
save pointer to skip all messages that were in between of removed
receive marker and process_info request.
To observe this behaviour using a debugger, run the test case
provided with a breakpoint set to handle_process_info part where
it reassigns c_p->sig_qs.cont to the next non-message signal
(**next_nm_sig)
Test case runs a process that triggers receive marker to enter
its middle queue. Currently it's done with process_info BIF, but
can also be triggered with erlang:cancel_timer (which also
places receive marker). Additional processes are sending
process_info requesting to move messages into inner queue, which
eventually makes middle queue to contain:
Receive marker gets removed from the middle queue after setting
save pointer to sig_qs.cont, then erts_proc_sig_handle_incoming
proceeds to process_info. Which moves reply tuple into the
inner queue, but save pointer is left untouched pointing to the
head of the middle queue, which is beyond the reply. This
way reply never gets matched (as save pointer has already
moved past it), and process_info hangs forever.