-
-
Notifications
You must be signed in to change notification settings - Fork 1.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
system/excpt: check if the exception is not nil before pop #18247
Conversation
In CPS we would consume an exception in the except branch by stashing it into a local then remove the exception from Nim environment so as not to leak it to other code that would be running before the continuation continues However since popCurrentException() assumes that the exception always exist, removing the exception from an except branch will cause a SIGSEGV to happen. This commit fixes that.
You pop the entire stack via |
Yes, since we control that stack in CPS.
|
I don't think for eg, if I wrap when true:
proc main =
# code from tests/exception/tsetexceptions.nim:
let ex = newException(CatchableError, "test")
setCurrentException(ex)
doAssert getCurrentException().msg == ex.msg
doAssert getCurrentExceptionMsg() == ex.msg
setCurrentException(nil)
try:
raise newException(CatchableError, "test2")
except:
setCurrentException(nil)
doAssert getCurrentException() == nil
try:
raise newException(CatchableError, "test3")
except:
try:
main()
except Exception as e:
echo "caught main: ", e.msg
echo "caught top"
let e2 = getCurrentException()
echo e2.msg # SIGSEGV yes, there is a
can you give more details? And doesn't that prevent using this as library code? instead of |
It should still be allowed, just with a warning in the docs regarding its influence on an exception handler.
In CPS, an exception handler might not be run in one go (ie. they perform a yield in the middle), thus we have to store and control what the "current" exception is in the view of the handler so they can resume their work. Imagine: proc foo() {.cps: Continuation.} =
try:
raise newException(CatchableError, "test")
except CatchableError:
pause() # pause the continuation until resumed
doAssert getCurrentExceptionMsg() == "test" To scope the exception to the handler in the continuation, CPS set the global "current" exception to what is captured at the site of Thanks to your sample, I found that there is a bug in CPS' exception implementation: the removal of the global current exception would cause outside code that was handling an exception to no longer have it. |
Yeah, that seems a much better solution. |
…18247) In CPS we would consume an exception in the except branch by stashing it into a local then remove the exception from Nim environment so as not to leak it to other code that would be running before the continuation continues However since popCurrentException() assumes that the exception always exist, removing the exception from an except branch will cause a SIGSEGV to happen. This commit fixes that.
…im-lang#18247)" (nim-lang#18265) This reverts commit 0adb47a.
In CPS we would consume an exception in the except branch by stashing it
into a local then remove the exception from Nim environment so as not to
leak it to other code that would be running before the continuation
continues
However since popCurrentException() assumes that the exception always
exist, removing the exception from an except branch will cause a
SIGSEGV to happen. This commit fixes that.