diff --git a/lib/system.nim b/lib/system.nim index 5e575c814..642ee957f 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -190,6 +190,7 @@ type msg* {.exportc: "message".}: string ## the exception's message. Not ## providing an exception message ## is bad style. + trace: string EAsynch* = object of E_Base ## Abstract exception class for ## *asynchronous exceptions* (interrupts). @@ -1900,6 +1901,10 @@ when not defined(EcmaScript) and not defined(NimrodVM): when hostOS != "standalone": proc getStackTrace*(): string ## gets the current stack trace. This is only works for debug builds. + + proc getStackTrace*(e: ref E_Base): string + ## gets the stack trace associated with `e`, which is the stack that + ## lead to the ``raise`` statement. This is only works for debug builds. {.push stack_trace: off.} when hostOS == "standalone": diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index a523e4e04..204fba376 100755 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -194,6 +194,9 @@ proc quitOrDebug() {.inline.} = proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} = e.name = ename + when hasSomeStackTrace: + e.trace = "" + rawWriteStackTrace(e.trace) if localRaiseHook != nil: if not localRaiseHook(e): return if globalRaiseHook != nil: @@ -253,6 +256,12 @@ proc getStackTrace(): string = else: result = "No stack traceback available\n" +proc getStackTrace(e: ref E_Base): string = + if not isNil(e) and not isNil(e.trace): + result = e.trace + else: + result = "" + when defined(endb): var dbgAborting: bool # whether the debugger wants to abort