diff options
author | Ștefan Talpalaru <stefantalpalaru@yahoo.com> | 2019-12-29 15:46:01 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-12-29 15:46:01 +0100 |
commit | ee9ee297d8d79ae17438343a6cb590906609f734 (patch) | |
tree | 5404ecae45279a44877ac58e041ba0c50ce92fc8 /lib/system | |
parent | 37e93eab668d836826be9eb334bb77bcf95f38af (diff) | |
download | Nim-ee9ee297d8d79ae17438343a6cb590906609f734.tar.gz |
generic stack trace overriding mechanism (#12922)
* libbacktrace support * switch to a generic stack trace overriding mechanism When "nimStackTraceOverride" is defined, once of the imported modules can register its own procedure to replace the default stack trace generation by calling `registerStackTraceOverride(myOwnProc)`. Tested with `./koch boot -d:release --debugger:native -d:nimStackTraceOverride --import:libbacktrace` for the compiler itself and `./bin/nim c -r -f --stacktrace:off --debugger:native -d:nimStackTraceOverride --import:libbacktrace foo.nim` for an external program. * make the StackTraceOverrideProc {.noinline.}
Diffstat (limited to 'lib/system')
-rw-r--r-- | lib/system/excpt.nim | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 6e06b10f8..140cd00b8 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -140,8 +140,23 @@ proc closureIterSetupExc(e: ref Exception) {.compilerproc, inline.} = const nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and not NimStackTrace - hasSomeStackTrace = NimStackTrace or - defined(nativeStackTrace) and nativeStackTraceSupported + hasSomeStackTrace = NimStackTrace or defined(nimStackTraceOverride) or + (defined(nativeStackTrace) and nativeStackTraceSupported) + +when defined(nimStackTraceOverride): + type StackTraceOverrideProc* = proc (): string {.nimcall, noinline, benign, raises: [], tags: [].} + ## Procedure type for overriding the default stack trace. + + var stackTraceOverrideGetTraceback: StackTraceOverrideProc = proc(): string {.noinline.} = + result = "Stack trace override procedure not registered.\n" + + proc registerStackTraceOverride*(overrideProc: StackTraceOverrideProc) = + ## Override the default stack trace inside rawWriteStackTrace() with your + ## own procedure. + stackTraceOverrideGetTraceback = overrideProc + + proc auxWriteStackTraceWithOverride(s: var string) = + add(s, stackTraceOverrideGetTraceback()) when defined(nativeStacktrace) and nativeStackTraceSupported: type @@ -289,7 +304,10 @@ proc stackTraceAvailable*(): bool when hasSomeStackTrace: proc rawWriteStackTrace(s: var string) = - when NimStackTrace: + when defined(nimStackTraceOverride): + add(s, "Traceback (most recent call last, using override)\n") + auxWriteStackTraceWithOverride(s) + elif NimStackTrace: if framePtr == nil: add(s, "No stack traceback available\n") else: @@ -308,7 +326,9 @@ when hasSomeStackTrace: s = @[] proc stackTraceAvailable(): bool = - when NimStackTrace: + when defined(nimStackTraceOverride): + result = true + elif NimStackTrace: if framePtr == nil: result = false else: @@ -443,12 +463,15 @@ proc raiseExceptionEx(e: sink(ref Exception), ename, procname, filename: cstring line: int) {.compilerRtl, nodestroy.} = if e.name.isNil: e.name = ename when hasSomeStackTrace: - if e.trace.len == 0: - rawWriteStackTrace(e.trace) - elif framePtr != nil: - e.trace.add reraisedFrom(reraisedFromBegin) - auxWriteStackTrace(framePtr, e.trace) - e.trace.add reraisedFrom(reraisedFromEnd) + when defined(nimStackTraceOverride): + e.trace = @[] + elif NimStackTrace: + if e.trace.len == 0: + rawWriteStackTrace(e.trace) + elif framePtr != nil: + e.trace.add reraisedFrom(reraisedFromBegin) + auxWriteStackTrace(framePtr, e.trace) + e.trace.add reraisedFrom(reraisedFromEnd) else: if procname != nil and filename != nil: e.trace.add StackTraceEntry(procname: procname, filename: filename, line: line) |