PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/code/target-exception.lisp

http://github.com/sbcl/sbcl
Lisp | 153 lines | 92 code | 10 blank | 51 comment | 0 complexity | 602576d1fa61aee5906c7a4ff2a1958a MD5 | raw file
Possible License(s): CC0-1.0
  1. ;;;; code for handling Win32 exceptions
  2. ;;;; This software is part of the SBCL system. See the README file for
  3. ;;;; more information.
  4. ;;;;
  5. ;;;; This software is derived from the CMU CL system, which was
  6. ;;;; written at Carnegie Mellon University and released into the
  7. ;;;; public domain. The software is in the public domain and is
  8. ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
  9. ;;;; files for more information.
  10. (in-package "SB-WIN32")
  11. ;;;
  12. ;;; An awful lot of this stuff is stubbed out for now. We basically
  13. ;;; only handle inbound exceptions (the local equivalent to unblockable
  14. ;;; signals), and we're only picking off the sigsegv and sigfpe traps.
  15. ;;;
  16. ;;; This file is based on target-signal.lisp, but most of that went
  17. ;;; away. Some of it might want to be put back or emulated.
  18. ;;;
  19. ;;; SIGINT is handled like BREAK, except that ANSI BREAK ignores
  20. ;;; *DEBUGGER-HOOK*, but we want SIGINT's BREAK to respect it, so that
  21. ;;; SIGINT in --disable-debugger mode will cleanly terminate the system
  22. ;;; (by respecting the *DEBUGGER-HOOK* established in that mode).
  23. ;;;
  24. ;;; We'd like to have this work, but that would require some method of
  25. ;;; delivering a "blockable signal". Windows doesn't really have the
  26. ;;; concept, so we need to play with the threading functions to emulate
  27. ;;; it (especially since the local equivalent of SIGINT comes in on a
  28. ;;; separate thread). This is on the list for fixing later on, and will
  29. ;;; be required before we implement threads (because of stop-for-gc).
  30. ;;;
  31. ;;; This specific bit of functionality may well be implemented entirely
  32. ;;; in the runtime.
  33. #||
  34. (defun sigint-%break (format-string &rest format-arguments)
  35. (flet ((break-it ()
  36. (apply #'%break 'sigint format-string format-arguments)))
  37. (sb-thread:interrupt-thread (sb-thread::foreground-thread) #'break-it)))
  38. ||#
  39. ;;; Map Windows Exception code to condition names: symbols or strings
  40. (defvar *exception-code-map*
  41. (macrolet ((cons-name (symbol)
  42. `(cons ,symbol ,(remove #\+ (substitute #\_ #\- (string symbol))))))
  43. (list
  44. ;; Floating point exceptions
  45. (cons +exception-flt-divide-by-zero+ 'division-by-zero)
  46. (cons +exception-flt-invalid-operation+ 'floating-point-invalid-operation)
  47. (cons +exception-flt-underflow+ 'floating-point-underflow)
  48. (cons +exception-flt-overflow+ 'floating-point-overflow)
  49. (cons +exception-flt-inexact-result+ 'floating-point-inexact)
  50. (cons +exception-flt-denormal-operand+ 'floating-point-exception)
  51. (cons +exception-flt-stack-check+ 'floating-point-exception)
  52. ;; Stack overflow
  53. (cons +exception-stack-overflow+ 'sb-kernel::control-stack-exhausted)
  54. ;; Various
  55. (cons-name +exception-single-step+)
  56. (cons +exception-access-violation+ 'memory-fault-error)
  57. (cons-name +exception-array-bounds-exceeded+)
  58. (cons-name +exception-breakpoint+)
  59. (cons-name +exception-datatype-misalignment+)
  60. (cons-name +exception-illegal-instruction+)
  61. (cons-name +exception-in-page-error+)
  62. (cons-name +exception-int-divide-by-zero+)
  63. (cons-name +exception-int-overflow+)
  64. (cons-name +exception-invalid-disposition+)
  65. (cons-name +exception-noncontinuable-exception+)
  66. (cons-name +exception-priv-instruction+))))
  67. (define-alien-type ()
  68. (struct exception-record
  69. (exception-code dword)
  70. (exception-flags dword)
  71. (exception-record system-area-pointer)
  72. (exception-address system-area-pointer)
  73. (number-parameters dword)
  74. (exception-information (array system-area-pointer
  75. #.+exception-maximum-parameters+))))
  76. ;;; DBG_PRINTEXCEPTION_C shouldn't be fatal, and even if it is related to
  77. ;;; something bad, better to print the message than just fail with no info
  78. (defun dbg-printexception-c (record)
  79. (when (= (slot record 'number-parameters) 2)
  80. ;; (sap-int (deref (slot record 'exception-information) 0)) =
  81. ;; length of string including 0-terminator
  82. (warn "DBG_PRINTEXCEPTION_C: ~a"
  83. (cast
  84. (sap-alien (deref (slot record 'exception-information) 1)
  85. (* char))
  86. c-string))))
  87. (defun dbg-printexception-wide-c (record)
  88. (when (= (slot record 'number-parameters) 4)
  89. ;; (sap-alien (deref (slot record 'exception-information) 3)) =
  90. ;; WideCharToMultiByte string
  91. (warn "DBG_PRINTEXCEPTION_WIDE_C: ~a"
  92. (cast
  93. (sap-alien (deref (slot record 'exception-information) 1)
  94. (* char))
  95. system-string))))
  96. (define-condition exception (error)
  97. ((code :initarg :code :reader exception-code)
  98. (context :initarg :context :reader exception-context)
  99. (record :initarg :record :reader exception-record))
  100. (:report (lambda (c s)
  101. (format s "An exception occurred in context ~S: ~S. (Exception code: ~S)"
  102. (exception-context c)
  103. (exception-record c)
  104. (exception-code c)))))
  105. ;;; Actual exception handler. We hit something the runtime doesn't
  106. ;;; want to or know how to deal with (that is, not a sigtrap or gc wp
  107. ;;; violation), so it calls us here.
  108. (defun sb-kernel:handle-win32-exception (context-sap exception-record-sap)
  109. (let* ((record (deref (sap-alien exception-record-sap (* (struct exception-record)))))
  110. (code (slot record 'exception-code))
  111. (condition-name (cdr (assoc code *exception-code-map*)))
  112. (sb-debug:*stack-top-hint* (sb-kernel:find-interrupted-frame)))
  113. (cond ((stringp condition-name)
  114. (error condition-name))
  115. ((and condition-name
  116. (subtypep condition-name 'arithmetic-error))
  117. (multiple-value-bind (op operands)
  118. (sb-di::decode-arithmetic-error-operands context-sap)
  119. ;; Reset the accumulated exceptions
  120. (setf (ldb sb-vm:float-sticky-bits (sb-vm:floating-point-modes)) 0)
  121. (error condition-name :operation op
  122. :operands operands)))
  123. ((eq condition-name 'memory-fault-error)
  124. (error 'memory-fault-error :address
  125. (sap-int (deref (slot record 'exception-information) 1))))
  126. (condition-name
  127. (error condition-name))
  128. ((= code +dbg-printexception-c+)
  129. (dbg-printexception-c record))
  130. ((= code +dbg-printexception-wide-c+)
  131. (dbg-printexception-wide-c record))
  132. (t
  133. (cerror "Return from the exception handler"
  134. 'exception :context context-sap :record exception-record-sap
  135. :code code)))))
  136. (in-package "SB-UNIX")
  137. (defun sb-kernel:signal-cold-init-or-reinit ()
  138. "Enable all the default signals that Lisp knows how to deal with."
  139. (unblock-deferrable-signals)
  140. (values))