summary refs log tree commit diff stats
path: root/lib/system/excpt.nim
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2020-03-30 04:45:32 -0700
committerGitHub <noreply@github.com>2020-03-30 13:45:32 +0200
commit19cab9fa51fdb9a244ca35e978e9daa8cc81a785 (patch)
tree18200faaf701d17e1980f31bfa6c3833a6dfba5e /lib/system/excpt.nim
parent8088633250872de8777c7078e636b2379780e107 (diff)
downloadNim-19cab9fa51fdb9a244ca35e978e9daa8cc81a785.tar.gz
stacktraces can now show custom runtime msgs per frame (#13351)
* stacktraces can now show custom runtime msgs
* improve tests/stdlib/tstackframes.nim
* fix test for --gc:arc
* test --stacktraceMsgs:on and --stacktraceMsgs:off
* --stacktracemsgs:off by default
Diffstat (limited to 'lib/system/excpt.nim')
-rw-r--r--lib/system/excpt.nim24
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 8ac47d26b..76d188ea6 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -53,6 +53,8 @@ type
     len: int
     prev: ptr GcFrameHeader
 
+when NimStackTraceMsgs:
+  var frameMsgBuf* {.threadvar.}: string
 var
   framePtr {.threadvar.}: PFrame
   excHandler {.threadvar.}: PSafePoint
@@ -224,10 +226,17 @@ proc auxWriteStackTrace(f: PFrame; s: var seq[StackTraceEntry]) =
     s[last] = StackTraceEntry(procname: it.procname,
                               line: it.line,
                               filename: it.filename)
+    when NimStackTraceMsgs:
+      let first = if it.prev == nil: 0 else: it.prev.frameMsgLen
+      if it.frameMsgLen > first:
+        s[last].frameMsg.setLen(it.frameMsgLen - first)
+        # somehow string slicing not available here
+        for i in first .. it.frameMsgLen-1:
+          s[last].frameMsg[i-first] = frameMsgBuf[i]
     it = it.prev
     dec last
 
-template addFrameEntry(s, f: untyped) =
+template addFrameEntry(s: var string, f: StackTraceEntry|PFrame) =
   var oldLen = s.len
   add(s, f.filename)
   if f.line > 0:
@@ -236,6 +245,12 @@ template addFrameEntry(s, f: untyped) =
     add(s, ')')
   for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ')
   add(s, f.procname)
+  when NimStackTraceMsgs:
+    when type(f) is StackTraceEntry:
+      add(s, f.frameMsg)
+    else:
+      var first = if f.prev == nil: 0 else: f.prev.frameMsgLen
+      for i in first..<f.frameMsgLen: add(s, frameMsgBuf[i])
   add(s, "\n")
 
 proc `$`(s: seq[StackTraceEntry]): string =
@@ -519,7 +534,12 @@ proc callDepthLimitReached() {.noinline.} =
   quit(1)
 
 proc nimFrame(s: PFrame) {.compilerRtl, inl, raises: [].} =
-  s.calldepth = if framePtr == nil: 0 else: framePtr.calldepth+1
+  if framePtr == nil:
+    s.calldepth = 0
+    when NimStackTraceMsgs: s.frameMsgLen = 0
+  else:
+    s.calldepth = framePtr.calldepth+1
+    when NimStackTraceMsgs: s.frameMsgLen = framePtr.frameMsgLen
   s.prev = framePtr
   framePtr = s
   if s.calldepth == nimCallDepthLimit: callDepthLimitReached()