-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
175 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
(in-package #:sbcl-librarian) | ||
|
||
(defvar *print-backtrace-in-bug* nil) | ||
|
||
(define-condition lisp-error (cl:error) | ||
((reason :initarg :reason | ||
:accessor lisp-error-reason) | ||
(args :initarg :args | ||
:accessor lisp-error-args)) | ||
(:report (lambda (c s) | ||
(with-slots (reason args) c | ||
(let ((*print-circle* nil)) | ||
(format s "Lisp Error: ~?" reason args)))))) | ||
|
||
(declaim (inline error)) | ||
(defun error (reason &rest args) | ||
(declare (type string reason)) | ||
(cl:error 'lisp-error | ||
:reason reason | ||
:args args)) | ||
|
||
(define-condition lisp-warning (style-warning) | ||
((reason :initarg :reason | ||
:accessor lisp-warning-reason) | ||
(args :initarg :args | ||
:accessor lisp-warning-args)) | ||
(:report (lambda (c s) | ||
(with-slots (reason args) c | ||
(let ((*print-circle* nil)) | ||
(format s "Lisp Warning: ~?" reason args)))))) | ||
|
||
(declaim (inline warning)) | ||
(defun warning (reason &rest args) | ||
(cl:warn 'lisp-warning | ||
:reason reason | ||
:args args)) | ||
|
||
(define-condition lisp-bug (cl:error) | ||
((reason :initarg :reason | ||
:accessor lisp-bug-reason) | ||
(args :initarg :args | ||
:accessor lisp-bug-args) | ||
(backtrace :initarg :backtrace | ||
:accessor lisp-bug-backtrace | ||
:initform (error "backtrace is required")) | ||
(context :initform (list) | ||
:accessor lisp-bug-context)) | ||
(:report (lambda (c s) | ||
(with-slots (reason args backtrace context) c | ||
(let ((*print-circle* nil)) | ||
(format s "Internal lisp bug: ~?~% | ||
If you are seeing this, please file an issue on Gitlab and include this error message in the description. | ||
~A | ||
Context: | ||
~{ ~{~A~^: ~}~%~} | ||
~A" | ||
reason | ||
args | ||
*gitlab-issue-url* | ||
context | ||
(if *print-backtrace-in-bug* | ||
backtrace | ||
""))))))) | ||
|
||
(declaim (inline bug)) | ||
(defun bug (reason &rest args) | ||
(declare (type string reason)) | ||
(cl:error 'lisp-bug | ||
:reason reason | ||
:args args | ||
:backtrace (with-output-to-string (s) | ||
(sb-debug:print-backtrace | ||
:stream s | ||
:start 1 ; Don't show the `bug' call | ||
:emergency-best-effort t)))) | ||
|
||
(declaim (inline unreachable)) | ||
(defun unreachable () | ||
(bug "unreachable")) | ||
|
||
(defmacro with-bug-context (context &body body) | ||
`(handler-bind | ||
((lisp-bug | ||
(lambda (c) | ||
(declare (ignorable c)) | ||
,@(mapcar (lambda (ctx) | ||
(cl:assert (= 2 (length ctx))) | ||
`(push (list ,@ctx) (lisp-bug-context c))) | ||
context)))) | ||
,@body)) | ||
|
||
(defmacro assert (test-form &optional places datum arguments) | ||
(let ((sym (gensym))) | ||
`(with-bug-context (,@(mapcar (lambda (place) | ||
`(,(format nil "~S" place) ,place)) | ||
places)) | ||
(let ((,sym ,test-form)) | ||
(unless ,sym | ||
(bug ,(or datum "The assertion ~S failed") | ||
,@(if datum arguments `(',test-form)))))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
(in-package #:sbcl-librarian) | ||
|
||
(define-enum-type error-type "lisp_err_t" | ||
("LISP_ERR_SUCCESS" 0) | ||
("LISP_ERR_FAILURE" 1) | ||
("LISP_ERR_BUG" 2) | ||
("LISP_ERR_FATAL" 3)) | ||
|
||
(defvar *error-message* "" | ||
"The most recent error message.") | ||
|
||
(defun get-error-message () | ||
*error-message*) | ||
|
||
(defvar *show-backtrace* nil) | ||
|
||
(defun enable-backtrace (code) | ||
(setf *show-backtrace* (not (zerop code)))) | ||
|
||
(defun crash () | ||
(error "oops")) | ||
|
||
(defun exhaust-heap () | ||
(sb-sys:without-gcing | ||
(let ((test '())) | ||
(loop (push 1 test))))) | ||
|
||
(define-error-map default-error-map error-type (:no-error 0 :fatal-error 3) | ||
((warning #'continue) | ||
|
||
(sbcl-librarian:lisp-error | ||
(lambda (c) | ||
(when *show-backtrace* | ||
(sb-debug:print-backtrace | ||
:stream *error-output* | ||
:emergency-best-effort t)) | ||
(setf *error-message* (format nil "~A" c)) | ||
(return-from default-error-map 1))) | ||
|
||
(sbcl-librarian:lisp-bug | ||
(lambda (c) | ||
(when *show-backtrace* | ||
(sb-debug:print-backtrace | ||
:stream *error-output* | ||
:emergency-best-effort t)) | ||
|
||
(let ((sbcl-librarian:*print-backtrace-in-bug* t)) | ||
(setf *error-message* (format nil "~A" c))) | ||
|
||
(return-from default-error-map 2))) | ||
|
||
(error | ||
(lambda (c) | ||
(let ((bug (make-instance 'sbcl-librarian:lisp-bug | ||
:reason (format nil "~A" c) | ||
:args nil | ||
:backtrace (with-output-to-string (s) | ||
(sb-debug:print-backtrace | ||
:stream s | ||
:emergency-best-effort t))))) | ||
|
||
(let ((sbcl-librarian:*print-backtrace-in-bug* t)) | ||
(setf *error-message* (format nil "~A" bug))) | ||
|
||
(return-from default-error-map 2)))))) | ||
|
||
(sbcl-librarian:define-api errors (:error-map default-error-map) | ||
(:literal "/* lisp */") | ||
(:type error-type) | ||
(:function | ||
(get-error-message :string ()) | ||
(enable-backtrace :void ((on :int))) | ||
(crash :void ()) | ||
(exhaust-heap :void ()))) |