Skip to content

Change exit() to Fatal(); make it possible to throw on Fatal(). #5087

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

Merged
merged 7 commits into from
Oct 1, 2022

Conversation

brson
Copy link
Contributor

@brson brson commented Sep 27, 2022

This patch makes binaryen easier to call from other applications by making more errors recoverable instead of early-exiting.

The main thing it does is change three calls to exit on I/O errors into calls to Fatal(), which is an existing custom abstraction for handling unrecoverable errors. Currently Fatal's destructor calls _Exit(1).

My intent is to make it possible for Fatal to not exit, but to throw, allowing an embedding application to catch the exception.

Because the previous early exits were exiting with error code EXIT_FAILURE, I also changed Fatal to exit with EXIT_FAILURE. The test suite continues to pass so I assume this is ok.

Next I changed Fatal to buffer its error message until the destructor instead of immediately printing it to stderr. This is for ease of patching Fatal to throw instead.

Finally, I also included the patch I need to make Fatal throw when THROW_ON_FATAL is defined at compile time. I can carry this patch out of tree, but it is a small patch, so perhaps you will be willing to take it. I am happy to remove it.

The aforementioned patch throws in a dtor, which is so strongly discouraged that it requires a special noexcept(false) annotation in c++17, the pitfall being that it is easy to throw during unwinding, which causes an abort. This is a special type though that only exists on error paths, and this solution is the smallest solution that might work for my use case. I have accounted for double throws by inserting an explicit abort in that case.

I have run the test suite successfully, but have not manually tested that fatal errors print the same as previously. I have tested that the patch throws exceptions that can be recovered in my project https://github.com/brson/wasm-opt-rs

Fixes #4938

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

Sounds good to me!

We should document that flag perhaps. At least in the changelog, but maybe there could be a section in the readme for emdedding? That section might also link to the rust bindings actually.

@brson
Copy link
Contributor Author

brson commented Sep 29, 2022 via email

@kripken
Copy link
Member

kripken commented Sep 29, 2022

I see, thanks. That goes beyond my understanding of C++ exceptions 😄 I'd be ok either with removing it or a comment that explains it.

@brson
Copy link
Contributor Author

brson commented Sep 30, 2022

I've updated the THROW_ON_FATAL patch with comments about throwing in destructors and removed the explicit abort; and added a commit that mentions it in the changelog.

I have contacted you on discord about how to best document it.

I think there's a lint error yet that I am waiting on ci again to look at.

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

This seems reasonable for now. Perhaps we can improve things further later but I don't have an idea how atm, and there is no harm in adding this now to help the Rust bindings.

@brson
Copy link
Contributor Author

brson commented Sep 30, 2022

Updated for the lint.

@kripken kripken enabled auto-merge (squash) September 30, 2022 22:52
@kripken kripken merged commit 22f0f3a into WebAssembly:main Oct 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

file.cpp calls exit instead of throwing exception
2 participants