Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,9 @@ type
CatchableError* = object of Exception ## \
## Abstract class for all exceptions that are catchable.

when defined(nimStackTraceOverride):
proc `=copy`*(x: var StackTraceEntry, y: StackTraceEntry) {.error.}

when defined(nimIcIntegrityChecks):
include "system/exceptions"

Expand Down
28 changes: 24 additions & 4 deletions lib/system/stacktraces.nim
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ when defined(nimStackTraceOverride):
proc (programCounters: seq[cuintptr_t], maxLength: cint): seq[StackTraceEntry] {.
nimcall, gcsafe, raises: [], tags: [], noinline.}


const NimStackTraceMsgs = compileOption("stacktraceMsgs")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused code?


# Default procedures (not normally used, because people opting in on this
# override are supposed to register their own versions).
var
Expand Down Expand Up @@ -65,6 +68,23 @@ when defined(nimStackTraceOverride):
for i in 0..<programCounters.len:
s.add(StackTraceEntry(programCounter: cast[uint](programCounters[i])))

proc copyStackTraceEntry(x: ptr StackTraceEntry): StackTraceEntry =
result = StackTraceEntry(line: x.line, programCounter: x.programCounter,
procnameStr: x.procnameStr, filenameStr: x.filenameStr
)
when NimStackTraceMsgs:
result.frameMsg = x.frameMsg

# points `procname`, `filename` to its own corresponding fields
# to avoid dangling pointers # bug #25306 18039
result.procname = result.procnameStr.cstring
result.filename = result.filenameStr.cstring

proc copyStackTraceEntrySeq(result: var seq[StackTraceEntry]; s: seq[StackTraceEntry]) =
for i in 0..<s.len:
let entry = addr s[i]
result.add(copyStackTraceEntry entry)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to copy anything here, all you need to do it to patch every entry after an add operation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking, in this particular case, one would want to move the existing entries...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add operation triggers a copy, which is marked {.error.}. Perhaps I need to use nodestroy or something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

patch entries after an add.

# We may have more stack trace lines in the output, due to inlined procedures.
proc addDebuggingInfo*(s: seq[StackTraceEntry]): seq[StackTraceEntry] =
var programCounters: seq[cuintptr_t]
Expand All @@ -75,10 +95,10 @@ when defined(nimStackTraceOverride):
if entry.procname.isNil and entry.programCounter != 0:
programCounters.add(cast[cuintptr_t](entry.programCounter))
elif entry.procname.isNil and (entry.line == reraisedFromBegin or entry.line == reraisedFromEnd):
result.add(stackTraceOverrideGetDebuggingInfo(programCounters, maxStackTraceLines))
result.copyStackTraceEntrySeq(stackTraceOverrideGetDebuggingInfo(programCounters, maxStackTraceLines))
programCounters = @[]
result.add(entry[])
result.add(copyStackTraceEntry entry)
else:
result.add(entry[])
result.add(copyStackTraceEntry entry)
if programCounters.len > 0:
result.add(stackTraceOverrideGetDebuggingInfo(programCounters, maxStackTraceLines))
result.copyStackTraceEntrySeq(stackTraceOverrideGetDebuggingInfo(programCounters, maxStackTraceLines))
Loading