Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug introduced by preventing unwind through stack bottom #81956

Merged
merged 1 commit into from
Feb 10, 2023

Conversation

janvorli
Copy link
Member

@janvorli janvorli commented Feb 10, 2023

The recent fix to prevent unwinding through stack bottom was incorrect for secondary threads, as it just compared the SP being above the frame of the hosting API. However, other threads can have their stacks anywhere in the memory, thus this sometimes broke exception handling on secondary threads.

I have also found that there was one more case where the unwind through the hosting API need to be checked - the Thread::VirtualUnwindToFirstManagedCallFrame.

I have decided to use the return address of the hosting API for the checks instead of the frame address. That makes the check work properly.

Close #81869

The irecent fix to prevent unwinding through stack bottom was
incorrect for secondary threads, as it just compared the SP
being above the frame of the hosting API. However, other threads
can have their stacks anywhere in the memory, thus this
sometimes broke exception handling on secondary threads.

I have also found that there was one more case where the
unwind through the hosting API need to be checked - the
Thread::VirtualUnwindToFirstManagedCallFrame.

I have decided to use the return address of the hosting
API for the checks instead of the frame address. That
makes the check work properly.
@janvorli
Copy link
Member Author

/azp run runtime-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkoritzinsky
Copy link
Member

Will this work if someone has a .NET plugin to their unmanaged app and calls a function pointer to an UnmanagedCallersOnly function from a thread that has never called the nethost APIs or managed code?

@janvorli
Copy link
Member Author

@jkoritzinsky the scenario you described is unrelated to the issue. We don't support propagating exceptions across the native / managed boundary for external native code on Unix.

@janvorli
Copy link
Member Author

One CI failure is a known issue and the other is unrelated to the change - an assert in JIT under crossgen2.

@janvorli janvorli merged commit 2e9087a into dotnet:main Feb 10, 2023
janvorli added a commit that referenced this pull request Feb 10, 2023
The irecent fix to prevent unwinding through stack bottom was
incorrect for secondary threads, as it just compared the SP
being above the frame of the hosting API. However, other threads
can have their stacks anywhere in the memory, thus this
sometimes broke exception handling on secondary threads.

I have also found that there was one more case where the
unwind through the hosting API need to be checked - the
Thread::VirtualUnwindToFirstManagedCallFrame.

I have decided to use the return address of the hosting
API for the checks instead of the frame address. That
makes the check work properly.
carlossanlop pushed a commit that referenced this pull request Feb 10, 2023
The irecent fix to prevent unwinding through stack bottom was
incorrect for secondary threads, as it just compared the SP
being above the frame of the hosting API. However, other threads
can have their stacks anywhere in the memory, thus this
sometimes broke exception handling on secondary threads.

I have also found that there was one more case where the
unwind through the hosting API need to be checked - the
Thread::VirtualUnwindToFirstManagedCallFrame.

I have decided to use the return address of the hosting
API for the checks instead of the frame address. That
makes the check work properly.
carlossanlop added a commit that referenced this pull request Feb 13, 2023
* Prevent unwinding through stack bottom

When processing unhandled exception on the most recent Alpine 3.17,
the libunwind doesn't stop at the bottom
frame of the main thread (the caller of `main`) and tries to unwind
further. The reason is that the method is missing dwarf unwind
information, so the libunwind falls back to using RBP chain, but the RBP
points to a garbage and so it ends up crashing with SIGSEGV.

While the missing DWARF unwind info seems to be a bug in the Alpine 3.17
(older ones work fine), we can prevent issues like this by stopping at
the hosting API boundary and not trying to unwind past that. This is
what this PR does.

* Fix bug introduced by preventing unwind through stack bottom (#81956)

The irecent fix to prevent unwinding through stack bottom was
incorrect for secondary threads, as it just compared the SP
being above the frame of the hosting API. However, other threads
can have their stacks anywhere in the memory, thus this
sometimes broke exception handling on secondary threads.

I have also found that there was one more case where the
unwind through the hosting API need to be checked - the
Thread::VirtualUnwindToFirstManagedCallFrame.

I have decided to use the return address of the hosting
API for the checks instead of the frame address. That
makes the check work properly.

---------

Co-authored-by: Jan Vorlicek <[email protected]>
Co-authored-by: Carlos Sanchez <[email protected]>
carlossanlop pushed a commit that referenced this pull request Feb 13, 2023
* Prevent unwinding through stack bottom

When processing unhandled exception on the most recent Alpine 3.17,
the libunwind doesn't stop at the bottom
frame of the main thread (the caller of `main`) and tries to unwind
further. The reason is that the method is missing dwarf unwind
information, so the libunwind falls back to using RBP chain, but the RBP
points to a garbage and so it ends up crashing with SIGSEGV.

While the missing DWARF unwind info seems to be a bug in the Alpine 3.17
(older ones work fine), we can prevent issues like this by stopping at
the hosting API boundary and not trying to unwind past that. This is
what this PR does.

* Fix bug introduced by preventing unwind through stack bottom (#81956)

The irecent fix to prevent unwinding through stack bottom was
incorrect for secondary threads, as it just compared the SP
being above the frame of the hosting API. However, other threads
can have their stacks anywhere in the memory, thus this
sometimes broke exception handling on secondary threads.

I have also found that there was one more case where the
unwind through the hosting API need to be checked - the
Thread::VirtualUnwindToFirstManagedCallFrame.

I have decided to use the return address of the hosting
API for the checks instead of the frame address. That
makes the check work properly.

---------

Co-authored-by: Jan Vorlicek <[email protected]>
@ghost ghost locked as resolved and limited conversation to collaborators Mar 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Test failure baseservices/exceptions/regressions/V1/SEH/COOL/rethrow/rethrow.sh
3 participants