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.}
This commit is contained in:
parent
37e93eab66
commit
ee9ee297d8
1 changed files with 33 additions and 10 deletions
|
|
@ -140,8 +140,23 @@ proc closureIterSetupExc(e: ref Exception) {.compilerproc, inline.} =
|
||||||
const
|
const
|
||||||
nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and
|
nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and
|
||||||
not NimStackTrace
|
not NimStackTrace
|
||||||
hasSomeStackTrace = NimStackTrace or
|
hasSomeStackTrace = NimStackTrace or defined(nimStackTraceOverride) or
|
||||||
defined(nativeStackTrace) and nativeStackTraceSupported
|
(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:
|
when defined(nativeStacktrace) and nativeStackTraceSupported:
|
||||||
type
|
type
|
||||||
|
|
@ -289,7 +304,10 @@ proc stackTraceAvailable*(): bool
|
||||||
|
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
proc rawWriteStackTrace(s: var string) =
|
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:
|
if framePtr == nil:
|
||||||
add(s, "No stack traceback available\n")
|
add(s, "No stack traceback available\n")
|
||||||
else:
|
else:
|
||||||
|
|
@ -308,7 +326,9 @@ when hasSomeStackTrace:
|
||||||
s = @[]
|
s = @[]
|
||||||
|
|
||||||
proc stackTraceAvailable(): bool =
|
proc stackTraceAvailable(): bool =
|
||||||
when NimStackTrace:
|
when defined(nimStackTraceOverride):
|
||||||
|
result = true
|
||||||
|
elif NimStackTrace:
|
||||||
if framePtr == nil:
|
if framePtr == nil:
|
||||||
result = false
|
result = false
|
||||||
else:
|
else:
|
||||||
|
|
@ -443,12 +463,15 @@ proc raiseExceptionEx(e: sink(ref Exception), ename, procname, filename: cstring
|
||||||
line: int) {.compilerRtl, nodestroy.} =
|
line: int) {.compilerRtl, nodestroy.} =
|
||||||
if e.name.isNil: e.name = ename
|
if e.name.isNil: e.name = ename
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
if e.trace.len == 0:
|
when defined(nimStackTraceOverride):
|
||||||
rawWriteStackTrace(e.trace)
|
e.trace = @[]
|
||||||
elif framePtr != nil:
|
elif NimStackTrace:
|
||||||
e.trace.add reraisedFrom(reraisedFromBegin)
|
if e.trace.len == 0:
|
||||||
auxWriteStackTrace(framePtr, e.trace)
|
rawWriteStackTrace(e.trace)
|
||||||
e.trace.add reraisedFrom(reraisedFromEnd)
|
elif framePtr != nil:
|
||||||
|
e.trace.add reraisedFrom(reraisedFromBegin)
|
||||||
|
auxWriteStackTrace(framePtr, e.trace)
|
||||||
|
e.trace.add reraisedFrom(reraisedFromEnd)
|
||||||
else:
|
else:
|
||||||
if procname != nil and filename != nil:
|
if procname != nil and filename != nil:
|
||||||
e.trace.add StackTraceEntry(procname: procname, filename: filename, line: line)
|
e.trace.add StackTraceEntry(procname: procname, filename: filename, line: line)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue