|
This change fixes issue with exception unwinding in the case when the unwinding
passed through a frame of the CallDescrWorkerInternal function. This function
had personality routine on it, but a windows style personality routine was specified.
The windows one has a completely different signature, so the code was crashing.
When looking into that, I've found that even if I have implemented a proper
Unix style personality routine, it cannot work the same way on Linux as it
used to work on Windows.
This personality routine's goal is to pop Frames from the Frame list in the current
thread so that all frames upto the frame handling the exception are popped.
There are two problems on Linux. First, unlike on Windows, the personality
routine is not passed the RSP of the frame handling the exception in an official
way. Although it can be extracted from the private_2 member of the exception
object during the 2nd pass, it is an implementation detail that we cannot rely on.
Moreover, even if we used that, it would still not be the right frame in all cases
due to the fact that we implement exception filters by catching and rethrowing and
so the frame we would get would be the frame of a filtering catch in case
there was one.
My solution to this problem is to add destructor to the Frame type and let it
pop the frame being destroyed if it is still in the list in the current thread.
That way the native code unwinding automatically takes care of popping the frames.
As an additional changes, I've added handling of the case when the
Thread::VirtualUnwindToFirstManagedCallFrame walks out of stack, fixed a stack
alignment issue in the recently added StartUnwindingNativeFrames function and
a cosmetic change in the UnwindManagedExceptionPass1.
|