Bug #20310
closedASAN fake stacks need to be marked during GC for non-current execution context
Description
When ASAN (address sanitizer) is enabled, the compiler does not necessarily store all local variables on the real machine stack; instead, locals can be stored in per-frame heap allocated memory which ASAN uses to detect things like stack-use-after-return ("fake stacks"). A pointer to the fake stack is left on the real machine stack, so it's possible to discover these fake stacks during GC and mark locals stored there as well.
At the moment, Ruby is currently marking these fake stacks for the current execution context which triggered GC, as part of mark_current_machine_context
: https://github.com/ruby/ruby/blob/fe0b704df5553bdd59e90650ffbbfac785a2e48a/gc.c#L6411. However, there are other machine stacks which also need to be marked like this:
- Machine stacks for other threads which did not trigger GC are marked in
rb_execution_context_mark
here: https://github.com/ruby/ruby/blob/fe0b704df5553bdd59e90650ffbbfac785a2e48a/vm.c#L3422 - Machine stacks for fibers are marked in
cont_mark
here: https://github.com/ruby/ruby/blob/fe0b704df5553bdd59e90650ffbbfac785a2e48a/cont.c#L1030
We need to make these two kinds of stacks perform the same ASAN fake stack marking as mark_current_machine_context
does.
(P.S. - callcc
continuations are another kind of machine stack which get marked, but ASAN is not compatible with callcc, so this doesn't really matter).
(P.S. - it appears to me that the currently-switched-to fiber will have its stack marked twice; once in rb_execution_context_mark
or mark_current_machine_context, and once in
cont_mark`; if this is true, I will fix this too)