X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fsave.lisp;h=1ddf475c3aa6641ef54e4e8ebb044a6affd5cbe4;hb=4d31006db24db375cdb83a5726d66c524b36689c;hp=4aa940a8a7c6f1844cd8d8e35a2f1997a3b76db4;hpb=04ee798422795a1e3d664c257a6b02b833eec4c6;p=sbcl.git diff --git a/src/code/save.lisp b/src/code/save.lisp index 4aa940a..1ddf475 100644 --- a/src/code/save.lisp +++ b/src/code/save.lisp @@ -20,22 +20,25 @@ (define-alien-routine "save" (boolean) (file c-string) (initial-fun (unsigned #.sb!vm:n-word-bits)) - (prepend-runtime int)) + (prepend-runtime int) + (save-runtime-options int)) #!+gencgc (define-alien-routine "gc_and_save" void (file c-string) - (prepend-runtime int)) + (prepend-runtime int) + (save-runtime-options int)) #!+gencgc (defvar sb!vm::*restart-lisp-function*) (defun save-lisp-and-die (core-file-name &key (toplevel #'toplevel-init) + (executable nil) + (save-runtime-options nil) (purify t) (root-structures ()) - (environment-name "auxiliary") - (executable nil)) + (environment-name "auxiliary")) #!+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. @@ -46,13 +49,22 @@ The following &KEY arguments are defined: :TOPLEVEL The function to run when the created core file is resumed. The default function handles command line toplevel option processing - and runs the top level read-eval-print loop. This function should - not return. + and runs the top level read-eval-print loop. This function returning + is equivalent to (SB-EXT:QUIT :UNIX-STATUS 0) being called. :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. + core image will not be executable on its own. Executable images + always behave as if they were passed the --noinform runtime option. + + :SAVE-RUNTIME-OPTIONS + If true, values of runtime options --dynamic-space-size and + --control-stack-size that were used to start SBCL are stored in + the standalone executable, and restored when the executable is + run. This also inhibits normal runtime option processing, causing + all command line arguments to be passed to the toplevel. + Meaningless if :EXECUTABLE is NIL. :PURIFY If true (the default on cheneygc), do a purifying GC which moves all @@ -83,12 +95,8 @@ The save/load process changes the values of some global variables: 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. +SAVE-LISP-AND-DIE interacts with SB-ALIEN:LOAD-SHARED-OBJECT: see its +documentation for details. On threaded platforms only a single thread may remain running after SB-EXT:*SAVE-HOOKS* have run. Applications using multiple threads can @@ -117,20 +125,30 @@ sufficiently motivated to do lengthy fixes." (labels ((restart-lisp () (handling-end-of-the-world (reinit) - (funcall toplevel))) + #!+hpux (sb!sys:%primitive sb!vm::setup-return-from-lisp-stub) + (progn + (funcall toplevel) + (sb!ext:quit)))) + (foreign-bool (value) + (if value 1 0)) (save-core (gc) - (when gc - #!-gencgc (gc) - ;; Do a destructive non-conservative GC, and then save a core. - ;; 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) - (if executable 1 0))) - (without-gcing - (save (unix-namestring core-file-name nil) - (get-lisp-obj-address #'restart-lisp) - (if executable 1 0))))) + (let ((name (native-namestring + (physicalize-pathname core-file-name) + :as-file t))) + (when gc + #!-gencgc (gc) + ;; Do a destructive non-conservative GC, and then save a core. + ;; 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 name + (foreign-bool executable) + (foreign-bool save-runtime-options))) + (without-gcing + (save name + (get-lisp-obj-address #'restart-lisp) + (foreign-bool executable) + (foreign-bool save-runtime-options)))))) ;; Save the restart function into a static symbol, to allow GC-AND-SAVE ;; access to it even after the GC has moved it. #!+gencgc @@ -147,15 +165,12 @@ sufficiently motivated to do lengthy fixes." (save-core t))))) (defun deinit () - (dolist (hook *save-hooks*) - (with-simple-restart (continue "Skip this save hook.") - (funcall hook))) + (call-hooks "save" *save-hooks*) (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)) + (foreign-deinit) + (stream-deinit) + (deinit-finalizers))