summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2017-01-20 12:40:47 +0100
committerAndreas Rumpf <rumpf_a@web.de>2017-01-20 12:40:54 +0100
commit7ff80cc8b2ec57b5797b3cf7d24d3b965ee2908a (patch)
tree89692dc830678bffb17778eba1aebe59417c07e3 /lib
parente22c36dfc28a93a7e8ac69ce377f085c28871606 (diff)
downloadNim-7ff80cc8b2ec57b5797b3cf7d24d3b965ee2908a.tar.gz
first implementation of segfaults stdlib module
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/segfaults.nim54
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)