-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
WIP: Uncatchable fatal errors #15906
base: master
Are you sure you want to change the base?
Conversation
How could adding a check to the top of every I strongly dislike opening the door to packages defining their exceptions as fatal in this uncatchable way without any clean workarounds (aside from trying to overwrite those methods, which can be unreliable with inlining). Any exception type where |
14183bf
to
51bdd4a
Compare
51bdd4a
to
28e3e88
Compare
rethrow_if_fatal(error) = isfatal(error) && ccall(:jl_rethrow_fatal, Void, ()) | ||
else | ||
rethrow_if_fatal(error) = nothing | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rethrow_if_fatal
is disabled for coreimg.jl
for now because it causes the following error in the first pass of inference.jl
compilation:
inference.jl
error during bootstrap:
UndefVarError(var=:Base)
rec_backtrace at /Users/sam/git/octech/julia/julia/src/stackwalk.c:83
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Analysis:
The try/catch
in pure_eval_call
ended up calling to promote_to_supertype
, which was calling error("no promotion exists for ", Float16, " and ", Int64)
. However, error
was defined as throw(Main.Base.ErrorException(Main.Base.string(s...)))
, and Base
does not exist when building coreimg.jl
, so the result was UndefVarError(var=:Base)
.
Fix:
Define a simple version of error
that works without Base
:
type CoreErrorException <: Exception
msg
end
error(s...) = throw(CoreErrorException(s))
cfc60f7
to
85c1193
Compare
238167f
to
d3b10ce
Compare
The implementation in this PR passing now passes all the CI tests. @JeffBezanson, @StefanKarpinski: any comments on the Note: So far this feature has found one place in |
This bug would have equally been detected if |
@nalimilan I agree. I have been advocating for I have read your comments in #15514 to the effect that a properly designed try/catch annotation system would make a special mechanism for abandonment-on-bugs unnecessary. I think you are probably right, and I hope that we get there sooner rather than later. I have a feeling that Joe Duffy's explicit differentiation bugs and exceptions has merit and should not be set aside lightly. However, it could be that a unified implementation handles both and the distinction only has to be made through documentation and API design conventions. |
Can we get a rebase on this? Is this something we're still interested in doing? |
I'm happy to spend the time to rebase if someone with commit access is interested in reviewing and merging this... |
This feature will become interesting if we can throw fatal exception early, or delay throwing them, or throw them out of order, because this will allow re-arranging code during optimization. (For example, one could change the order in which a loop is traversed, and indexing errors might then be reported for a different (later) index than without such a reordering.) Is that possible with this design? |
See #15514
Interface
try
causes ordinary errors to disappear as usual:try
no longer catches fatal errors:The
isfatal
function decides which errors are fatal:Handling of fatal exceptions can be reenabled for a particular stack frame (e.g. for the REPL,
@test_throws
, RPC, etc...):Implementation
A call to
rethrow_if_fatal
is inserted at the top of thecatch
block:rethrow_if_fatal()
rethrows fatal exceptions unless, e.g., the REPL wants to catch fatal exceptions at a particular stack frame.The REPL calls
Base.enable_catch_fatal()
ineval_user_input
. This allows it to catch and display fatal errors as usual.