This commit is contained in:
Araq 2015-04-27 23:11:36 +02:00
commit c6398d408d
9 changed files with 107 additions and 81 deletions

View file

@ -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):