parent
bc1db0d6f1
commit
c555525227
3 changed files with 33 additions and 10 deletions
|
|
@ -154,6 +154,11 @@ proc c_fwrite*(buf: pointer, size, n: csize_t, f: CFilePtr): cint {.
|
||||||
proc c_fflush(f: CFilePtr): cint {.
|
proc c_fflush(f: CFilePtr): cint {.
|
||||||
importc: "fflush", header: "<stdio.h>".}
|
importc: "fflush", header: "<stdio.h>".}
|
||||||
|
|
||||||
|
proc rawWriteString*(f: CFilePtr, s: cstring, length: int) {.compilerproc, nonReloadable, inline.} =
|
||||||
|
# we cannot throw an exception here!
|
||||||
|
discard c_fwrite(s, 1, cast[csize_t](length), f)
|
||||||
|
discard c_fflush(f)
|
||||||
|
|
||||||
proc rawWrite*(f: CFilePtr, s: cstring) {.compilerproc, nonReloadable, inline.} =
|
proc rawWrite*(f: CFilePtr, s: cstring) {.compilerproc, nonReloadable, inline.} =
|
||||||
# we cannot throw an exception here!
|
# we cannot throw an exception here!
|
||||||
discard c_fwrite(s, 1, cast[csize_t](s.len), f)
|
discard c_fwrite(s, 1, cast[csize_t](s.len), f)
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,17 @@ when defined(windows):
|
||||||
|
|
||||||
when not defined(windows) or not defined(guiapp):
|
when not defined(windows) or not defined(guiapp):
|
||||||
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
|
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
|
||||||
|
proc writeToStdErr(msg: cstring, length: int) =
|
||||||
|
rawWriteString(cstderr, msg, length)
|
||||||
else:
|
else:
|
||||||
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
|
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
|
||||||
header: "<windows.h>", nodecl.}
|
header: "<windows.h>", nodecl.}
|
||||||
proc writeToStdErr(msg: cstring) =
|
proc writeToStdErr(msg: cstring) =
|
||||||
discard MessageBoxA(nil, msg, nil, 0)
|
discard MessageBoxA(nil, msg, nil, 0)
|
||||||
|
proc writeToStdErr(msg: cstring, length: int) =
|
||||||
|
discard MessageBoxA(nil, msg, nil, 0)
|
||||||
|
|
||||||
proc showErrorMessage(data: cstring) {.gcsafe, raises: [].} =
|
proc showErrorMessage(data: cstring, length: int) {.gcsafe, raises: [].} =
|
||||||
var toWrite = true
|
var toWrite = true
|
||||||
if errorMessageWriter != nil:
|
if errorMessageWriter != nil:
|
||||||
try:
|
try:
|
||||||
|
|
@ -45,7 +49,7 @@ proc showErrorMessage(data: cstring) {.gcsafe, raises: [].} =
|
||||||
# stderr not available by default, use the LOG session
|
# stderr not available by default, use the LOG session
|
||||||
echo data
|
echo data
|
||||||
else:
|
else:
|
||||||
writeToStdErr(data)
|
writeToStdErr(data, length)
|
||||||
|
|
||||||
proc chckIndx(i, a, b: int): int {.inline, compilerproc, benign.}
|
proc chckIndx(i, a, b: int): int {.inline, compilerproc, benign.}
|
||||||
proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.}
|
proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.}
|
||||||
|
|
@ -359,7 +363,7 @@ proc reportUnhandledErrorAux(e: ref Exception) {.nodestroy.} =
|
||||||
if onUnhandledException != nil:
|
if onUnhandledException != nil:
|
||||||
onUnhandledException(buf)
|
onUnhandledException(buf)
|
||||||
else:
|
else:
|
||||||
showErrorMessage(buf)
|
showErrorMessage(buf, buf.len)
|
||||||
`=destroy`(buf)
|
`=destroy`(buf)
|
||||||
else:
|
else:
|
||||||
# ugly, but avoids heap allocations :-)
|
# ugly, but avoids heap allocations :-)
|
||||||
|
|
@ -388,7 +392,7 @@ proc reportUnhandledErrorAux(e: ref Exception) {.nodestroy.} =
|
||||||
if onUnhandledException != nil:
|
if onUnhandledException != nil:
|
||||||
onUnhandledException($tbuf())
|
onUnhandledException($tbuf())
|
||||||
else:
|
else:
|
||||||
showErrorMessage(tbuf())
|
showErrorMessage(tbuf(), L)
|
||||||
|
|
||||||
proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
|
proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
|
||||||
if unhandledExceptionHook != nil:
|
if unhandledExceptionHook != nil:
|
||||||
|
|
@ -500,9 +504,9 @@ proc writeStackTrace() =
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
var s = ""
|
var s = ""
|
||||||
rawWriteStackTrace(s)
|
rawWriteStackTrace(s)
|
||||||
cast[proc (s: cstring) {.noSideEffect, tags: [], nimcall, raises: [].}](showErrorMessage)(s)
|
cast[proc (s: cstring, length: int) {.noSideEffect, tags: [], nimcall, raises: [].}](showErrorMessage)(s, s.len)
|
||||||
else:
|
else:
|
||||||
cast[proc (s: cstring) {.noSideEffect, tags: [], nimcall, raises: [].}](showErrorMessage)("No stack traceback available\n")
|
cast[proc (s: cstring, length: int) {.noSideEffect, tags: [], nimcall, raises: [].}](showErrorMessage)("No stack traceback available\n", 32)
|
||||||
|
|
||||||
proc getStackTrace(): string =
|
proc getStackTrace(): string =
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
|
|
@ -535,10 +539,11 @@ const nimCallDepthLimit {.intdefine.} = 2000
|
||||||
|
|
||||||
proc callDepthLimitReached() {.noinline.} =
|
proc callDepthLimitReached() {.noinline.} =
|
||||||
writeStackTrace()
|
writeStackTrace()
|
||||||
showErrorMessage("Error: call depth limit reached in a debug build (" &
|
let msg = "Error: call depth limit reached in a debug build (" &
|
||||||
$nimCallDepthLimit & " function calls). You can change it with " &
|
$nimCallDepthLimit & " function calls). You can change it with " &
|
||||||
"-d:nimCallDepthLimit=<int> but really try to avoid deep " &
|
"-d:nimCallDepthLimit=<int> but really try to avoid deep " &
|
||||||
"recursions instead.\n")
|
"recursions instead.\n"
|
||||||
|
showErrorMessage(msg, msg.len)
|
||||||
quit(1)
|
quit(1)
|
||||||
|
|
||||||
proc nimFrame(s: PFrame) {.compilerRtl, inl, raises: [].} =
|
proc nimFrame(s: PFrame) {.compilerRtl, inl, raises: [].} =
|
||||||
|
|
@ -622,14 +627,14 @@ when not defined(noSignalHandler) and not defined(useNimRtl):
|
||||||
var buf = newStringOfCap(2000)
|
var buf = newStringOfCap(2000)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
processSignal(sign, buf.add) # nice hu? currying a la Nim :-)
|
processSignal(sign, buf.add) # nice hu? currying a la Nim :-)
|
||||||
showErrorMessage(buf)
|
showErrorMessage(buf, buf.len)
|
||||||
when not usesDestructors: GC_enable()
|
when not usesDestructors: GC_enable()
|
||||||
else:
|
else:
|
||||||
var msg: cstring
|
var msg: cstring
|
||||||
template asgn(y) =
|
template asgn(y) =
|
||||||
msg = y
|
msg = y
|
||||||
processSignal(sign, asgn)
|
processSignal(sign, asgn)
|
||||||
showErrorMessage(msg)
|
showErrorMessage(msg, msg.len)
|
||||||
quit(1) # always quit when SIGABRT
|
quit(1) # always quit when SIGABRT
|
||||||
|
|
||||||
proc registerSignalHandler() =
|
proc registerSignalHandler() =
|
||||||
|
|
|
||||||
13
tests/exception/t13115.nim
Normal file
13
tests/exception/t13115.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
discard """
|
||||||
|
exitcode: 1
|
||||||
|
targets: "c"
|
||||||
|
matrix: "-d:debug; -d:release"
|
||||||
|
outputsub: '''t13115.nim(13) t13115
|
||||||
|
Error: unhandled exception: This char is'''
|
||||||
|
outputsub: ''' and works fine! [Exception]'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
const b_null: char = 0.char
|
||||||
|
var msg = "This char is `" & $b_null & "` and works fine!"
|
||||||
|
|
||||||
|
raise newException(Exception, msg)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue