Skip to content

Commit ee9ee29

Browse files
stefantalpalaruAraq
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.}
1 parent 37e93ea commit ee9ee29

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
@@ -140,8 +140,23 @@ proc closureIterSetupExc(e: ref Exception) {.compilerproc, inline.} =
140140
const
141141
nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and
142142
not NimStackTrace
143-
hasSomeStackTrace = NimStackTrace or
144-
defined(nativeStackTrace) and nativeStackTraceSupported
143+
hasSomeStackTrace = NimStackTrace or defined(nimStackTraceOverride) or
144+
(defined(nativeStackTrace) and nativeStackTraceSupported)
145+
146+
when defined(nimStackTraceOverride):
147+
type StackTraceOverrideProc* = proc (): string {.nimcall, noinline, benign, raises: [], tags: [].}
148+
## Procedure type for overriding the default stack trace.
149+
150+
var stackTraceOverrideGetTraceback: StackTraceOverrideProc = proc(): string {.noinline.} =
151+
result = "Stack trace override procedure not registered.\n"
152+
153+
proc registerStackTraceOverride*(overrideProc: StackTraceOverrideProc) =
154+
## Override the default stack trace inside rawWriteStackTrace() with your
155+
## own procedure.
156+
stackTraceOverrideGetTraceback = overrideProc
157+
158+
proc auxWriteStackTraceWithOverride(s: var string) =
159+
add(s, stackTraceOverrideGetTraceback())
145160

146161
when defined(nativeStacktrace) and nativeStackTraceSupported:
147162
type
@@ -289,7 +304,10 @@ proc stackTraceAvailable*(): bool
289304

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

310328
proc stackTraceAvailable(): bool =
311-
when NimStackTrace:
329+
when defined(nimStackTraceOverride):
330+
result = true
331+
elif NimStackTrace:
312332
if framePtr == nil:
313333
result = false
314334
else:
@@ -443,12 +463,15 @@ proc raiseExceptionEx(e: sink(ref Exception), ename, procname, filename: cstring
443463
line: int) {.compilerRtl, nodestroy.} =
444464
if e.name.isNil: e.name = ename
445465
when hasSomeStackTrace:
446-
if e.trace.len == 0:
447-
rawWriteStackTrace(e.trace)
448-
elif framePtr != nil:
449-
e.trace.add reraisedFrom(reraisedFromBegin)
450-
auxWriteStackTrace(framePtr, e.trace)
451-
e.trace.add reraisedFrom(reraisedFromEnd)
466+
when defined(nimStackTraceOverride):
467+
e.trace = @[]
468+
elif NimStackTrace:
469+
if e.trace.len == 0:
470+
rawWriteStackTrace(e.trace)
471+
elif framePtr != nil:
472+
e.trace.add reraisedFrom(reraisedFromBegin)
473+
auxWriteStackTrace(framePtr, e.trace)
474+
e.trace.add reraisedFrom(reraisedFromEnd)
452475
else:
453476
if procname != nil and filename != nil:
454477
e.trace.add StackTraceEntry(procname: procname, filename: filename, line: line)

0 commit comments

Comments
 (0)