Fix grammar in lossage message
[sbcl.git] / src / code / save.lisp
blobbff958613d5cead82cce2bbe553d845b8f87bf6f
1 ;;;; Dump the current Lisp image into a core file. Also contains
2 ;;;; various high-level initialization stuff: loading init files and
3 ;;;; parsing environment variables.
4 ;;;;
5 ;;;; (All the real work is done by C.)
7 ;;;; This software is part of the SBCL system. See the README file for
8 ;;;; more information.
9 ;;;;
10 ;;;; This software is derived from the CMU CL system, which was
11 ;;;; written at Carnegie Mellon University and released into the
12 ;;;; public domain. The software is in the public domain and is
13 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
14 ;;;; files for more information.
16 (in-package "SB!IMPL")
18 ;;;; SAVE-LISP-AND-DIE itself
20 (define-alien-routine "save" (boolean)
21 (file c-string)
22 (initial-fun (unsigned #.sb!vm:n-word-bits))
23 (prepend-runtime int)
24 (save-runtime-options int)
25 (compressed int)
26 (compression-level int)
27 (application-type int))
29 #!+gencgc
30 (define-alien-routine "gc_and_save" void
31 (file c-string)
32 (prepend-runtime int)
33 (save-runtime-options int)
34 (compressed int)
35 (compression-level int)
36 (application-type int))
38 #!+gencgc
39 (defvar sb!vm::*restart-lisp-function*)
41 (define-condition save-condition (reference-condition)
43 (:default-initargs
44 :references (list '(:sbcl :node "Saving a Core Image"))))
46 (define-condition save-error (error save-condition)
48 (:report "Could not save core."))
50 (define-condition save-with-multiple-threads-error (save-error)
51 ((interactive-thread :initarg :interactive-threads
52 :reader save-with-multiple-threads-error-interactive-threads)
53 (other-threads :initarg :other-threads
54 :reader save-with-multiple-threads-error-other-threads))
55 (:report (lambda (condition stream)
56 (let ((interactive (save-with-multiple-threads-error-interactive-threads condition))
57 (other (save-with-multiple-threads-error-other-threads condition)))
58 (format stream "~@<Cannot save core with multiple threads running.~
59 ~@:_~@:_Interactive thread~P (of current session):~
60 ~@:_~2@T~<~{~A~^, ~}~:>~
61 ~@:_~@:_Other thread~P:~
62 ~@:_~2@T~<~{~A~^, ~}~:>~@:>"
63 (length interactive) (list interactive)
64 (length other) (list other))))))
66 (defun save-lisp-and-die (core-file-name &key
67 (toplevel #'toplevel-init)
68 (executable nil)
69 (save-runtime-options nil)
70 (purify t)
71 (root-structures ())
72 (environment-name "auxiliary")
73 (compression nil)
74 #!+win32
75 (application-type :console))
76 #!+sb-doc
77 "Save a \"core image\", i.e. enough information to restart a Lisp
78 process later in the same state, in the file of the specified name.
79 Only global state is preserved: the stack is unwound in the process.
81 The following &KEY arguments are defined:
83 :TOPLEVEL
84 The function to run when the created core file is resumed. The
85 default function handles command line toplevel option processing
86 and runs the top level read-eval-print loop. This function returning
87 is equivalent to (SB-EXT:EXIT :CODE 0) being called.
89 TOPLEVEL functions should always provide an ABORT restart: otherwise
90 code they call will run without one.
92 :EXECUTABLE
93 If true, arrange to combine the SBCL runtime and the core image
94 to create a standalone executable. If false (the default), the
95 core image will not be executable on its own. Executable images
96 always behave as if they were passed the --noinform runtime option.
98 :SAVE-RUNTIME-OPTIONS
99 If true, values of runtime options --dynamic-space-size and
100 --control-stack-size that were used to start SBCL are stored in
101 the standalone executable, and restored when the executable is
102 run. This also inhibits normal runtime option processing, causing
103 all command line arguments to be passed to the toplevel.
104 Meaningless if :EXECUTABLE is NIL.
106 :PURIFY
107 If true (the default on cheneygc), do a purifying GC which moves all
108 dynamically allocated objects into static space. This takes
109 somewhat longer than the normal GC which is otherwise done, but
110 it's only done once, and subsequent GC's will be done less often
111 and will take less time in the resulting core file. See the PURIFY
112 function. This parameter has no effect on platforms using the
113 generational garbage collector.
115 :ROOT-STRUCTURES
116 This should be a list of the main entry points in any newly loaded
117 systems. This need not be supplied, but locality and/or GC performance
118 may be better if they are. Meaningless if :PURIFY is NIL. See the
119 PURIFY function.
121 :ENVIRONMENT-NAME
122 This is also passed to the PURIFY function when :PURIFY is T.
123 (rarely used)
125 :COMPRESSION
126 This is only meaningful if the runtime was built with the :SB-CORE-COMPRESSION
127 feature enabled. If NIL (the default), saves to uncompressed core files. If
128 :SB-CORE-COMPRESSION was enabled at build-time, the argument may also be
129 an integer from -1 to 9, corresponding to zlib compression levels, or T
130 (which is equivalent to the default compression level, -1).
132 :APPLICATION-TYPE
133 Present only on Windows and is meaningful only with :EXECUTABLE T.
134 Specifies the subsystem of the executable, :CONSOLE or :GUI.
135 The notable difference is that :GUI doesn't automatically create a console
136 window. The default is :CONSOLE.
138 The save/load process changes the values of some global variables:
140 *STANDARD-OUTPUT*, *DEBUG-IO*, etc.
141 Everything related to open streams is necessarily changed, since
142 the OS won't let us preserve a stream across save and load.
144 *DEFAULT-PATHNAME-DEFAULTS*
145 This is reinitialized to reflect the working directory where the
146 saved core is loaded.
148 SAVE-LISP-AND-DIE interacts with SB-ALIEN:LOAD-SHARED-OBJECT: see its
149 documentation for details.
151 On threaded platforms only a single thread may remain running after
152 SB-EXT:*SAVE-HOOKS* have run. Applications using multiple threads can
153 be SAVE-LISP-AND-DIE friendly by registering a save-hook that quits
154 any additional threads, and an init-hook that restarts them.
156 This implementation is not as polished and painless as you might like:
157 * It corrupts the current Lisp image enough that the current process
158 needs to be killed afterwards. This can be worked around by forking
159 another process that saves the core.
160 * There is absolutely no binary compatibility of core images between
161 different runtime support programs. Even runtimes built from the same
162 sources at different times are treated as incompatible for this
163 purpose.
164 This isn't because we like it this way, but just because there don't
165 seem to be good quick fixes for either limitation and no one has been
166 sufficiently motivated to do lengthy fixes."
167 #!+gencgc
168 (declare (ignore purify root-structures environment-name))
169 #!+sb-core-compression
170 (check-type compression (or boolean (integer -1 9)))
171 #!-sb-core-compression
172 (when compression
173 (error "Unable to save compressed core: this runtime was not built with zlib support"))
174 (when *dribble-stream*
175 (restart-case (error "Dribbling to ~s is enabled." (pathname *dribble-stream*))
176 (continue ()
177 :report "Stop dribbling and save the core."
178 (dribble))
179 (abort ()
180 :report "Abort saving the core."
181 (return-from save-lisp-and-die))))
182 (when (eql t compression)
183 (setf compression -1))
184 (tune-image-for-dump)
185 (deinit)
186 ;; FIXME: Would it be possible to unmix the PURIFY logic from this
187 ;; function, and just do a GC :FULL T here? (Then if the user wanted
188 ;; a PURIFYed image, he'd just run PURIFY immediately before calling
189 ;; SAVE-LISP-AND-DIE.)
190 (labels ((restart-lisp ()
191 (handling-end-of-the-world
192 (reinit)
193 #!+hpux (%primitive sb!vm::setup-return-from-lisp-stub)
194 (funcall toplevel)))
195 (foreign-bool (value)
196 (if value 1 0))
197 (save-core (gc)
198 (let ((name (native-namestring
199 (physicalize-pathname core-file-name)
200 :as-file t)))
201 (when gc
202 #!-gencgc (gc)
203 ;; Do a destructive non-conservative GC, and then save a core.
204 ;; A normal GC will leave huge amounts of storage unreclaimed
205 ;; (over 50% on x86). This needs to be done by a single function
206 ;; since the GC will invalidate the stack.
207 #!+gencgc (gc-and-save name
208 (foreign-bool executable)
209 (foreign-bool save-runtime-options)
210 (foreign-bool compression)
211 (or compression 0)
212 #!+win32
213 (ecase application-type
214 (:console 0)
215 (:gui 1))
216 #!-win32 0))
217 (without-gcing
218 (save name
219 (get-lisp-obj-address #'restart-lisp)
220 (foreign-bool executable)
221 (foreign-bool save-runtime-options)
222 (foreign-bool compression)
223 (or compression 0)
224 #!+win32
225 (ecase application-type
226 (:console 0)
227 (:gui 1))
228 #!-win32 0)))))
229 ;; Save the restart function into a static symbol, to allow GC-AND-SAVE
230 ;; access to it even after the GC has moved it.
231 #!+gencgc
232 (setf sb!vm::*restart-lisp-function* #'restart-lisp)
233 (cond #!-gencgc
234 (purify
235 (purify :root-structures root-structures
236 :environment-name environment-name)
237 (save-core nil))
239 (save-core t)))
240 ;; Something went very wrong -- reinitialize to have a prayer
241 ;; of being able to report the error.
242 (reinit)
243 (error 'save-error)))
245 ;;; REPACK-XREF is defined during warm load of
246 ;;; src/code/repack-xref.lisp.
247 (declaim (ftype (sfunction (&key (:verbose t) (:compact-name-count (integer 0))) null)
248 sb!c::repack-xref))
249 (defun tune-image-for-dump ()
250 #!+sb-fasteval (sb!interpreter::flush-everything)
251 (tune-hashtable-sizes-of-all-packages)
252 (sb!c::repack-xref :verbose nil))
254 (defun deinit ()
255 (call-hooks "save" *save-hooks*)
256 #!+sb-wtimer
257 (itimer-emulation-deinit)
258 (let ((threads (sb!thread:list-all-threads)))
259 (unless (= 1 (length threads))
260 (let* ((interactive (sb!thread::interactive-threads))
261 (other (set-difference threads interactive)))
262 (error 'save-with-multiple-threads-error
263 :interactive-threads interactive
264 :other-threads other))))
265 (float-deinit)
266 (profile-deinit)
267 (foreign-deinit)
268 (stream-deinit)
269 (deinit-finalizers)
270 (drop-all-hash-caches)
271 (os-deinit)
272 (setf * nil ** nil *** nil
273 - nil + nil ++ nil +++ nil
274 /// nil // nil / nil))