(define-alien-routine "save" (boolean)
(file c-string)
- (initial-fun (unsigned #.sb!vm:n-word-bits)))
+ (initial-fun (unsigned #.sb!vm:n-word-bits))
+ (prepend-runtime int))
#!+gencgc
(define-alien-routine "gc_and_save" void
- (file c-string))
+ (file c-string)
+ (prepend-runtime int))
#!+gencgc
(defvar sb!vm::*restart-lisp-function*)
(purify #!+gencgc nil
#!-gencgc t)
(root-structures ())
- (environment-name "auxiliary"))
+ (environment-name "auxiliary")
+ (executable nil))
#!+sb-doc
"Save a \"core image\", i.e. enough information to restart a Lisp
process later in the same state, in the file of the specified name.
and runs the top level read-eval-print loop. This function should
not return.
+ :EXECUTABLE
+ If true, arrange to combine the SBCL runtime and the core image
+ to create a standalone executable. If false (the default), the
+ core image will not be executable on its own.
+
:PURIFY
If true (the default on cheneygc), do a purifying GC which moves all
dynamically allocated objects into static space. This takes
This is reinitialized to reflect the working directory where the
saved core is loaded.
-Foreign objects loaded with SB-ALIEN:LOAD-SHARED-OBJECT are
-automatically reloaded on startup, but references to foreign symbols
-do not survive intact on all platforms: in this case a WARNING is
-signalled when saving the core. If no warning is signalled, then the
-foreign symbol references will remain intact. Platforms where this is
-currently the case are x86/FreeBSD, x86/Linux, x86/NetBSD,
-sparc/Linux, sparc/SunOS, and ppc/Darwin.
+Foreign objects loaded with SB-ALIEN:LOAD-SHARED-OBJECT are automatically
+reloaded on startup, but references to foreign symbols do not survive intact
+on all platforms: in this case a WARNING is signalled when saving the core. If
+no warning is signalled, then the foreign symbol references will remain
+intact. Platforms where this is currently the case are x86/FreeBSD, x86/Linux,
+x86/NetBSD, sparc/Linux, sparc/SunOS, and ppc/Darwin.
+
+On threaded platforms only a single thread may remain running after
+SB-EXT:*SAVE-HOOKS* have run. Applications using multiple threads can
+be SAVE-LISP-AND-DIE friendly by registering a save-hook that quits
+any additional threads, and an init-hook that restarts them.
This implementation is not as polished and painless as you might like:
* It corrupts the current Lisp image enough that the current process
needs to be killed afterwards. This can be worked around by forking
another process that saves the core.
- * It will not work if multiple threads are in use.
* There is absolutely no binary compatibility of core images between
different runtime support programs. Even runtimes built from the same
sources at different times are treated as incompatible for this
;; A normal GC will leave huge amounts of storage unreclaimed
;; (over 50% on x86). This needs to be done by a single function
;; since the GC will invalidate the stack.
- #!+gencgc (gc-and-save (unix-namestring core-file-name nil)))
+ #!+gencgc (gc-and-save (unix-namestring core-file-name nil)
+ (if executable 1 0)))
(without-gcing
(save (unix-namestring core-file-name nil)
- (get-lisp-obj-address #'restart-lisp)))))
+ (get-lisp-obj-address #'restart-lisp)
+ (if executable 1 0)))))
;; Save the restart function into a static symbol, to allow GC-AND-SAVE
;; access to it even after the GC has moved it.
#!+gencgc
:environment-name environment-name)
(save-core nil))
(t
+ ;; Compact the environment even though we're skipping the
+ ;; other purification stages.
+ (sb!kernel::compact-environment-aux "Auxiliary" 200)
(save-core t)))))
(defun deinit ()
(dolist (hook *save-hooks*)
(with-simple-restart (continue "Skip this save hook.")
(funcall hook)))
+ (when (rest (sb!thread:list-all-threads))
+ (error "Cannot save core with multiple threads running."))
+ #!-win32
(when (fboundp 'cancel-finalization)
(cancel-finalization sb!sys:*tty*))
+ (float-deinit)
(profile-deinit)
(debug-deinit)
(foreign-deinit))