Skip to content

SIGSEGV in closure iterator with try/except not at top level #21235

@iffy

Description

@iffy

Description

UPDATED: The following code produces a SIGSEGV:

try:
  proc myFunc() =
    iterator myFuncIter(): int {.closure.} =
      if false:
        try:
          yield 5
        except:
          discard
    var nameIterVar = myFuncIter
    discard nameIterVar()
  try:
    raise ValueError.newException("foo")
  finally:
    myFunc()
except ValueError as exc:
  if exc.msg == "foo":
    echo "21235 ok"
  else:
    echo "21235 fail"

I now believe it happens because the try/except block is not the top block in the closure iterator.


Original report:

import std/asyncdispatch

proc myFunc*() {.async.} =
  if false:
    try:
      await newFuture[void]("Thing.myFunc")
    except:
      discard

try:
  raise ValueError.newException("foo")
finally:
  waitFor myFunc()
Traceback (most recent call last)
/Users/matt/tmp/t21235.nim(13) t21235
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

On my macOS machine, this minimal code produces a SIGSEGV.

import chronos

type
  Obj = ref object
    queue: AsyncQueue[string]

proc newQueue(o: Obj): AsyncQueue[string] =
  o.queue = newAsyncQueue[string]()
  return o.queue

block:
  var o = Obj()
  var oq = o.newQueue()
  defer: waitFor o.queue.addLast("foo")
  raise ValueError.newException("foo")

Taking any line out prevents the segfault.

Nim Version

Nim Compiler Version 1.6.10 [MacOSX: amd64]
Compiled at 2022-11-29
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release

Current Output

Traceback (most recent call last)
/tmp/test_tmp.nim(14) test_tmp
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

Expected Output

/tmp/test_tmp.nim(15) test_tmp
Error: unhandled exception: foo [ValueError]

Possible Solution

No response

Additional Information

If it's helpful, here's a portion of the core dump:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   test_tmp                      	0x0000000108c0af3e reportUnhandledErrorAux__system_3392 + 30
1   test_tmp                      	0x0000000108c0b2d5 reportUnhandledError__system_3409 + 53
2   test_tmp                      	0x0000000108c103fd nimLeaveFinally + 77
3   test_tmp                      	0x0000000108c25fbc NimMainModule + 636
4   test_tmp                      	0x0000000108c25d39 NimMainInner + 9
5   test_tmp                      	0x0000000108c2600a NimMain + 42
6   test_tmp                      	0x0000000108c2604e main + 62
7   libdyld.dylib                 	0x00007fff647d03d5 start + 1

Original issue I filed with chronos is here: status-im/nim-chronos#342 which includes this other version of the issue:

import chronos

type
  Obj = ref object
    queue: AsyncQueue[string]

proc newQueue(o: Obj): AsyncQueue[string] =
  o.queue = newAsyncQueue[string]()
  return o.queue

try:
  var o = Obj()
  var oq = o.newQueue()
  defer: waitFor o.queue.addLast("foo")
  raise (ref ValueError)(msg: "test")
except ValueError:
  echo "test"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions