fixes #1888
This commit is contained in:
parent
b34bd3b163
commit
c6398d408d
9 changed files with 107 additions and 81 deletions
|
|
@ -58,7 +58,7 @@ proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} =
|
|||
proc popSafePoint {.compilerRtl, inl.} =
|
||||
excHandler = excHandler.prev
|
||||
|
||||
proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} =
|
||||
proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} =
|
||||
e.parent = currException
|
||||
currException = e
|
||||
|
||||
|
|
@ -69,12 +69,12 @@ proc popCurrentException {.compilerRtl, inl.} =
|
|||
const
|
||||
nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and
|
||||
not NimStackTrace
|
||||
hasSomeStackTrace = NimStackTrace or
|
||||
hasSomeStackTrace = NimStackTrace or
|
||||
defined(nativeStackTrace) and nativeStackTraceSupported
|
||||
|
||||
when defined(nativeStacktrace) and nativeStackTraceSupported:
|
||||
type
|
||||
TDl_info {.importc: "Dl_info", header: "<dlfcn.h>",
|
||||
TDl_info {.importc: "Dl_info", header: "<dlfcn.h>",
|
||||
final, pure.} = object
|
||||
dli_fname: cstring
|
||||
dli_fbase: pointer
|
||||
|
|
@ -98,7 +98,7 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
|
|||
tempDlInfo: TDl_info
|
||||
# This is allowed to be expensive since it only happens during crashes
|
||||
# (but this way you don't need manual stack tracing)
|
||||
var size = backtrace(cast[ptr pointer](addr(tempAddresses)),
|
||||
var size = backtrace(cast[ptr pointer](addr(tempAddresses)),
|
||||
len(tempAddresses))
|
||||
var enabled = false
|
||||
for i in 0..size-1:
|
||||
|
|
@ -123,7 +123,7 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
|
|||
when not hasThreadSupport:
|
||||
var
|
||||
tempFrames: array [0..127, PFrame] # should not be alloc'd on stack
|
||||
|
||||
|
||||
proc auxWriteStackTrace(f: PFrame, s: var string) =
|
||||
when hasThreadSupport:
|
||||
var
|
||||
|
|
@ -160,7 +160,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
|
|||
inc(i)
|
||||
b = b.prev
|
||||
for j in countdown(i-1, 0):
|
||||
if tempFrames[j] == nil:
|
||||
if tempFrames[j] == nil:
|
||||
add(s, "(")
|
||||
add(s, $skipped)
|
||||
add(s, " calls omitted) ...")
|
||||
|
|
@ -214,41 +214,49 @@ proc raiseExceptionAux(e: ref Exception) =
|
|||
if not localRaiseHook(e): return
|
||||
if globalRaiseHook != nil:
|
||||
if not globalRaiseHook(e): return
|
||||
if excHandler != nil:
|
||||
if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
|
||||
pushCurrentException(e)
|
||||
c_longjmp(excHandler.context, 1)
|
||||
elif e[] of OutOfMemError:
|
||||
showErrorMessage(e.name)
|
||||
quitOrDebug()
|
||||
else:
|
||||
when hasSomeStackTrace:
|
||||
var buf = newStringOfCap(2000)
|
||||
if isNil(e.trace): rawWriteStackTrace(buf)
|
||||
else: add(buf, e.trace)
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
add(buf, $e.name)
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
when defined(cpp):
|
||||
if e[] of OutOfMemError:
|
||||
showErrorMessage(e.name)
|
||||
quitOrDebug()
|
||||
else:
|
||||
# ugly, but avoids heap allocations :-)
|
||||
template xadd(buf, s, slen: expr) =
|
||||
if L + slen < high(buf):
|
||||
copyMem(addr(buf[L]), cstring(s), slen)
|
||||
inc L, slen
|
||||
template add(buf, s: expr) =
|
||||
xadd(buf, s, s.len)
|
||||
var buf: array [0..2000, char]
|
||||
var L = 0
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
xadd(buf, e.name, c_strlen(e.name))
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
quitOrDebug()
|
||||
pushCurrentException(e)
|
||||
{.emit: "throw NimException(`e`, `e`->name);".}
|
||||
else:
|
||||
if excHandler != nil:
|
||||
if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
|
||||
pushCurrentException(e)
|
||||
c_longjmp(excHandler.context, 1)
|
||||
elif e[] of OutOfMemError:
|
||||
showErrorMessage(e.name)
|
||||
quitOrDebug()
|
||||
else:
|
||||
when hasSomeStackTrace:
|
||||
var buf = newStringOfCap(2000)
|
||||
if isNil(e.trace): rawWriteStackTrace(buf)
|
||||
else: add(buf, e.trace)
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
add(buf, $e.name)
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
else:
|
||||
# ugly, but avoids heap allocations :-)
|
||||
template xadd(buf, s, slen: expr) =
|
||||
if L + slen < high(buf):
|
||||
copyMem(addr(buf[L]), cstring(s), slen)
|
||||
inc L, slen
|
||||
template add(buf, s: expr) =
|
||||
xadd(buf, s, s.len)
|
||||
var buf: array [0..2000, char]
|
||||
var L = 0
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
xadd(buf, e.name, c_strlen(e.name))
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
quitOrDebug()
|
||||
|
||||
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
|
||||
e.name = ename
|
||||
|
|
@ -309,7 +317,7 @@ when not defined(noSignalHandler):
|
|||
proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
||||
template processSignal(s, action: expr) {.immediate, dirty.} =
|
||||
if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n")
|
||||
elif s == SIGSEGV:
|
||||
elif s == SIGSEGV:
|
||||
action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n")
|
||||
elif s == SIGABRT:
|
||||
when defined(endb):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue