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

Make longjmp over managed frames work #111259

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

janvorli
Copy link
Member

The new exception handling has broken hosting Lua on Windows when a Lua code throws an exception that ends up crossing managed frames. Lua uses longjmp for its exception handling mechanism and the new exception handling reported the longjmp as an unhandled SEHException.

This change makes the new EH ignore the STATUS_LONGJUMP exception when it passes through managed frames, so it can reach the target location. It is a best effort fix though, as finallys in the skipped frames won't be called.

Close #111242

The new exception handling has broken hosting Lua on Windows when
a Lua code throws an exception that ends up crossing managed frames.
Lua uses longjmp for its exception handling mechanism and the new
exception handling reported the longjmp as an unhandled `SEHException`.

This change makes the new EH ignore the `STATUS_LONGJUMP` exception
when it passes through managed frames, so it can reach the target
location. It is a best effort fix though, as finallys in the skipped
frames won't be called.

Close dotnet#111242
@janvorli janvorli added this to the 9.0.x milestone Jan 10, 2025
@janvorli janvorli requested a review from jkotas January 10, 2025 00:41
@janvorli janvorli self-assigned this Jan 10, 2025
@@ -932,6 +932,13 @@ ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord,

Thread* pThread = GetThread();

if (pExceptionRecord->ExceptionCode == STATUS_LONGJUMP)
{
// This is an exception used to unwind during longjmp function. We just let it pass through managed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to unwind Frames to avoid corrupting runtime data structures?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if we are unwinding Frames, is it that hard to call finallys too to match the old behavior?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had it implemented by propagating the exception through the managed frames as usual, so the finallys were called, and then re-issued the longjmp after processing them. The only missing part to do was preventing calling catch handlers. The old EH doesn't call those "naturally", as the longjmp runs only the unwind pass.
And then you've mentioned it was not supported, so I have deleted that code :-).
But anyways, I can change it back to that, the change wasn't complicated. The only thing is that the Unix handling would then be different.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing is that the Unix handling would then be different.

longjump over managed code does not and cannot work well on Unix, so I do not think it is a problem

@jkotas
Copy link
Member

jkotas commented Jan 10, 2025

If we want to "support this", should we add a test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SEHException with new Exception behavior in .NET 9
2 participants