X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fsave.lisp;h=8cefec9a5ccdb7b2b58b66a54591bd6eaf8ef069;hb=b36697e233ff1ef1cc3ad2e687581520656d4755;hp=b38cbca2ca90214cbcd0e764b229d60d758282e6;hpb=75b52379bdc2269961af6a1308eca63610f38ac3;p=sbcl.git diff --git a/src/code/save.lisp b/src/code/save.lisp index b38cbca..8cefec9 100644 --- a/src/code/save.lisp +++ b/src/code/save.lisp @@ -34,27 +34,16 @@ #!+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. - -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 - purpose. -This isn't because we like it this way, but just because there don't -seem to be good quick fixes for either limitation and no one has been -sufficiently motivated to do lengthy fixes. +Only global state is preserved: the stack is unwound in the process. 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. + :PURIFY If true (the default), do a purifying GC which moves all dynamically allocated objects into static space. This takes @@ -62,22 +51,47 @@ The following &KEY arguments are defined: it's only done once, and subsequent GC's will be done less often and will take less time in the resulting core file. See the PURIFY function. + :ROOT-STRUCTURES This should be a list of the main entry points in any newly loaded systems. This need not be supplied, but locality and/or GC performance may be better if they are. Meaningless if :PURIFY is NIL. See the PURIFY function. + :ENVIRONMENT-NAME This is also passed to the PURIFY function when :PURIFY is T. (rarely used) The save/load process changes the values of some global variables: + *STANDARD-OUTPUT*, *DEBUG-IO*, etc. Everything related to open streams is necessarily changed, since the OS won't let us preserve a stream across save and load. + *DEFAULT-PATHNAME-DEFAULTS* This is reinitialized to reflect the working directory where the - saved core is loaded." + 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. + +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 + purpose. +This isn't because we like it this way, but just because there don't +seem to be good quick fixes for either limitation and no one has been +sufficiently motivated to do lengthy fixes." (deinit) ;; FIXME: Would it be possible to unmix the PURIFY logic from this ;; function, and just do a GC :FULL T here? (Then if the user wanted @@ -89,8 +103,8 @@ The save/load process changes the values of some global variables: #-gencgc (gc) #+gencgc (gc :full t)) (flet ((restart-lisp () (handling-end-of-the-world - (reinit) - (funcall toplevel)))) + (reinit) + (funcall toplevel)))) ;; FIXME: Perhaps WITHOUT-GCING should be wrapped around the ;; LET as well, to avoid the off chance of an interrupt triggering ;; GC and making our saved RESTART-LISP address invalid? @@ -99,7 +113,9 @@ The save/load process changes the values of some global variables: (get-lisp-obj-address #'restart-lisp))))) (defun deinit () - (mapc #'funcall *save-hooks*) + (dolist (hook *save-hooks*) + (with-simple-restart (continue "Skip this save hook.") + (funcall hook))) (when (fboundp 'cancel-finalization) (cancel-finalization sb!sys:*tty*)) (profile-deinit)