Skip to content

Commit de43bdf

Browse files
stefantalpalarunarimiran
authored andcommitted
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.} (cherry picked from commit ee9ee29)
1 parent 25a4026 commit de43bdf

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

lib/system/excpt.nim

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,23 @@ proc closureIterSetupExc(e: ref Exception) {.compilerproc, inline.} =
139139
const
140140
nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and
141141
not NimStackTrace
142-
hasSomeStackTrace = NimStackTrace or
143-
defined(nativeStackTrace) and nativeStackTraceSupported
142+
hasSomeStackTrace = NimStackTrace or defined(nimStackTraceOverride) or
143+
(defined(nativeStackTrace) and nativeStackTraceSupported)
144+
145+
when defined(nimStackTraceOverride):
146+
type StackTraceOverrideProc* = proc (): string {.nimcall, noinline, benign, raises: [], tags: [].}
147+
## Procedure type for overriding the default stack trace.
148+
149+
var stackTraceOverrideGetTraceback: StackTraceOverrideProc = proc(): string {.noinline.} =
150+
result = "Stack trace override procedure not registered.\n"
151+
152+
proc registerStackTraceOverride*(overrideProc: StackTraceOverrideProc) =
153+
## Override the default stack trace inside rawWriteStackTrace() with your
154+
## own procedure.
155+
stackTraceOverrideGetTraceback = overrideProc
156+
157+
proc auxWriteStackTraceWithOverride(s: var string) =
158+
add(s, stackTraceOverrideGetTraceback())
144159

145160
when defined(nativeStacktrace) and nativeStackTraceSupported:
146161
type
@@ -288,7 +303,10 @@ proc stackTraceAvailable*(): bool
288303

289304
when hasSomeStackTrace:
290305
proc rawWriteStackTrace(s: var string) =
291-
when NimStackTrace:
306+
when defined(nimStackTraceOverride):
307+
add(s, "Traceback (most recent call last, using override)\n")
308+
auxWriteStackTraceWithOverride(s)
309+
elif NimStackTrace:
292310
if framePtr == nil:
293311
add(s, "No stack traceback available\n")
294312
else:
@@ -307,7 +325,9 @@ when hasSomeStackTrace:
307325
s = @[]
308326

309327
proc stackTraceAvailable(): bool =
310-
when NimStackTrace:
328+
when defined(nimStackTraceOverride):
329+
result = true
330+
elif NimStackTrace:
311331
if framePtr == nil:
312332
result = false
313333
else:
@@ -395,12 +415,15 @@ proc raiseExceptionAux(e: ref Exception) =
395415
proc raiseExceptionEx(e: ref Exception, ename, procname, filename: cstring, line: int) {.compilerRtl.} =
396416
if e.name.isNil: e.name = ename
397417
when hasSomeStackTrace:
398-
if e.trace.len == 0:
399-
rawWriteStackTrace(e.trace)
400-
elif framePtr != nil:
401-
e.trace.add reraisedFrom(reraisedFromBegin)
402-
auxWriteStackTrace(framePtr, e.trace)
403-
e.trace.add reraisedFrom(reraisedFromEnd)
418+
when defined(nimStackTraceOverride):
419+
e.trace = @[]
420+
elif NimStackTrace:
421+
if e.trace.len == 0:
422+
rawWriteStackTrace(e.trace)
423+
elif framePtr != nil:
424+
e.trace.add reraisedFrom(reraisedFromBegin)
425+
auxWriteStackTrace(framePtr, e.trace)
426+
e.trace.add reraisedFrom(reraisedFromEnd)
404427
else:
405428
if procname != nil and filename != nil:
406429
e.trace.add StackTraceEntry(procname: procname, filename: filename, line: line)

0 commit comments

Comments
 (0)