diff options
Diffstat (limited to 'lib/system/excpt.nim')
-rw-r--r-- | lib/system/excpt.nim | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 096d01845..950981227 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -73,12 +73,11 @@ proc popSafePoint {.compilerRtl, inl.} = excHandler = excHandler.prev proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} = - #if e.parent.isNil: - # e.parent = currException + e.up = currException currException = e proc popCurrentException {.compilerRtl, inl.} = - currException = nil # currException.parent + currException = currException.up # some platforms have native support for stack traces: const @@ -230,6 +229,18 @@ when false: pushCurrentException(e) c_longjmp(excHandler.context, 1) +var onUnhandledException*: (proc (errorMsg: string) {. + nimcall.}) ## set this error \ + ## handler to override the existing behaviour on an unhandled exception. + ## The default is to write a stacktrace to ``stderr`` and then call ``quit(1)``. + ## Unstable API. + +template unhandled(buf, body) = + if onUnhandledException != nil: + onUnhandledException($buf) + else: + body + proc raiseExceptionAux(e: ref Exception) = if localRaiseHook != nil: if not localRaiseHook(e): return @@ -260,14 +271,16 @@ proc raiseExceptionAux(e: ref Exception) = add(buf, " [") add(buf, $e.name) add(buf, "]\n") - showErrorMessage(buf) + unhandled(buf): + showErrorMessage(buf) + quitOrDebug() else: # ugly, but avoids heap allocations :-) - template xadd(buf, s, slen: expr) = + template xadd(buf, s, slen) = if L + slen < high(buf): copyMem(addr(buf[L]), cstring(s), slen) inc L, slen - template add(buf, s: expr) = + template add(buf, s) = xadd(buf, s, s.len) var buf: array[0..2000, char] var L = 0 @@ -276,8 +289,13 @@ proc raiseExceptionAux(e: ref Exception) = add(buf, " [") xadd(buf, e.name, e.name.len) add(buf, "]\n") - showErrorMessage(buf) - quitOrDebug() + when defined(nimNoArrayToCstringConversion): + template tbuf(): untyped = addr buf + else: + template tbuf(): untyped = buf + unhandled(tbuf()): + showErrorMessage(tbuf()) + quitOrDebug() proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = if e.name.isNil: e.name = ename @@ -373,7 +391,8 @@ when not defined(noSignalHandler): GC_enable() else: var msg: cstring - template asgn(y: expr) = msg = y + template asgn(y) = + msg = y processSignal(sign, asgn) showErrorMessage(msg) when defined(endb): dbgAborting = true |