crash when calling await within a try block within an except block
Example
import asyncdispatch
proc test() {.gcsafe, async.} =
try:
await sleepAsync(1000)
return
except CatchableError as err:
echo err.msg
var mrRuntime = true
try:
if mrRuntime:
raise newException(CatchableError, "Not implemented")
except CatchableError as err:
echo err.msg
waitFor test() # if this is in the `except` block it crashes - otherwise (unindent) it's fine
Current Output
Not implemented
Traceback (most recent call last)
/home/onqtam/a.nim(16) a
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Expected Output
Not implemented
Additional Information
This was happening with previous versions of the compiler as well. Note that if you move waitFor test() outside of the except block it will no longer crash.
I haven't looked if this exact bug has already been reported.
$ nim -v
Nim Compiler Version 1.2.2 [Linux: amd64]
Compiled at 2020-06-18
Copyright (c) 2006-2020 by Andreas Rumpf
git hash: be34b5abe23e027b71a3a9da67037aac7afea6bc
active boot switches: -d:release
still i am gonna check out if i know this bug
it seems https://github.com/alehander92/Nim/commit/d6d4f140dadc601dab3d17d61d58d152c58e8916 is a patch, but not sure why this happens
(currException becomes nil, that's why it crashes)
I believe I just ran into this same issue. Had a SIGSEGV and have a similar pattern in exception block, except in my case, a proc is called from the exception block, with a waitFor within it.
CC @yglukhov (might be related to the try-catch implementation for closure iterators?)
Hello,
I want to up this issue, because it is still present. it was also diffcult to figure out the bug in complex codebase, because the error is not explicit :
~/.choosenim/toolchains/nim-2.0.2/lib/pure/asyncfutures.nim(162) main (Async) SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Trying to compile with import std/segfaults results in an infinite busy loop.
For now the workaround is to put all code inside an async proc, so that the try/except calls only await. For example :
import asyncdispatch
proc test() {.gcsafe, async.} =
try:
await sleepAsync(1000)
return
except CatchableError as err:
echo err.msg
proc main() {.async.} =
var mrRuntime = true
try:
if mrRuntime:
raise newException(CatchableError, "Not implemented")
except CatchableError as err:
echo err.msg
await test() # if this is in the `except` block it crashes - otherwise (unindent) it's fine
waitFor main()