Fix issue with locals overlapping out of scope GCFrame (dotnet/coreclr#26763)
* Fix issue with locals overlapping out of scope GCFrame
More aggressive C/C++ optimizations done by VS2019 are breaking fragile
assumptions of the CoreCLR "manually managed code".
Unwinding of Frame chains accesses stack local variables after the stack
frame has been unwound, but it depends on their content to be left
intact. The new compiler is breaking this assumption by stack-packing a
different variable over it.
This change fixes the problem by adding a destructor to GCFrame that
pops the frame from the per-thread Frame list.
I also had to refactor two functions where the compiler was complaining
about mixing SEH and C++ EH in single function.
With these changes applied, there was still a problem that I've discovered
when running CoreCLR tests with GCStress 3. When the
ExceptionTracker::m_pInitialExplicitFrame was still pointing to a frame
that was already removed from the explicit Frame chain. When the
ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException was walking
the frame chain starting at m_pInitialExplicitFrame to figure out if a given
frame was already unwound, it has walked to the destroyed GCFrame and
crashed.
To fix that, the chain from the initial explicit frame is updated so
that it stays valid (effectively, the destroyed GCFrame is removed from
it). It was also necessary to handle the case when the destroyed GCFrame
was the ExceptionTracker::m_pLimitFrame. The limit frame needs to be
updated to the next frame so that it can be reached on the chain from
the initial explicit frame.
* Reflect PR feedback
Change the switching to coop mode in ~GCFrame from holder based to
manual.
Commit migrated from https://github.com/dotnet/coreclr/commit/
6059e75e13593b0820e178f8baaace32c09aca6e