diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2017-01-20 12:40:47 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-01-20 12:40:54 +0100 |
commit | 7ff80cc8b2ec57b5797b3cf7d24d3b965ee2908a (patch) | |
tree | 89692dc830678bffb17778eba1aebe59417c07e3 /lib | |
parent | e22c36dfc28a93a7e8ac69ce377f085c28871606 (diff) | |
download | Nim-7ff80cc8b2ec57b5797b3cf7d24d3b965ee2908a.tar.gz |
first implementation of segfaults stdlib module
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/segfaults.nim | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/pure/segfaults.nim b/lib/pure/segfaults.nim new file mode 100644 index 000000000..3c3b59449 --- /dev/null +++ b/lib/pure/segfaults.nim @@ -0,0 +1,54 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This modules registers a signal handler that turns access violations / +## segfaults into a ``NilAccessError`` exception. To be able to catch +## a NilAccessError all you have to do is to import this module. + +type + NilAccessError* = object of SystemError ## \ + ## Raised on dereferences of ``nil`` pointers. + +# do allocate memory upfront: +var se: ref NilAccessError +new(se) +se.msg = "" + +when defined(windows): + include "$lib/system/ansi_c" + + {.push stackTrace: off.} + proc segfaultHandler(sig: cint) {.noconv.} = + {.gcsafe.}: + raise se + {.pop.} + c_signal(SIGSEGV, segfaultHandler) + +else: + import posix + + var sa: Sigaction + + var SEGV_MAPERR {.importc, header: "<signal.h>".}: cint + + {.push stackTrace: off.} + proc segfaultHandler(sig: cint, y: var SigInfo, z: pointer) {.noconv.} = + if y.si_code == SEGV_MAPERR: + {.gcsafe.}: + raise se + else: + quit(1) + {.pop.} + + discard sigemptyset(sa.sa_mask) + + sa.sa_sigaction = segfaultHandler + sa.sa_flags = SA_SIGINFO or SA_NODEFER + + discard sigaction(SIGSEGV, sa) |