[Concurrency runtime] Don't read from the actor after transitioning state #66008
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.
Once we have transitioned the actor into a new state, we report the state change as a trace event so it can be noted by tools (e.g., Instruments). However, the act of transitioning to a new state can mean that there is an opportunity for another thread to deallocate the actor. This means that the tracing call cannot depend on dereferencing the actor pointer.
A refactoring a few months ago to move the bit that indicates when a distributed actor is remote from inside the atomic actor state out to a separate field (because it's constant for a given actor instance), which introduced a dereference of the actor instance in forming the tracing call. This introduced a narrow window in which a race condition could occur: the actor transitions to an idle state, and is then deallocate before the trace event for the actor transition occurs, leading to a use-after-free.
Fetch this bit of information earlier in the process, before any state changes and when we know the actor is still allocated, and pass it through to the tracing code.
Fixes rdar://108497870.