run-program: support I/O redirection to binary streams on win32.
[sbcl.git] / src / code / save.lisp
blob5f70a1c45634a7b3998ca8011c49a59d50f687eb
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 #!+sb-fasteval (sb!interpreter::flush-everything)
185 (tune-hashtable-sizes-of-all-packages)
186 (deinit)
187 ;; FIXME: Would it be possible to unmix the PURIFY logic from this
188 ;; function, and just do a GC :FULL T here? (Then if the user wanted
189 ;; a PURIFYed image, he'd just run PURIFY immediately before calling
190 ;; SAVE-LISP-AND-DIE.)
191 (labels ((restart-lisp ()
192 (handling-end-of-the-world
193 (reinit)
194 #!+hpux (%primitive sb!vm::setup-return-from-lisp-stub)
195 (funcall toplevel)))
196 (foreign-bool (value)
197 (if value 1 0))
198 (save-core (gc)
199 (let ((name (native-namestring
200 (physicalize-pathname core-file-name)
201 :as-file t)))
202 (when gc
203 #!-gencgc (gc)
204 ;; Do a destructive non-conservative GC, and then save a core.
205 ;; A normal GC will leave huge amounts of storage unreclaimed
206 ;; (over 50% on x86). This needs to be done by a single function
207 ;; since the GC will invalidate the stack.
208 #!+gencgc (gc-and-save name
209 (foreign-bool executable)
210 (foreign-bool save-runtime-options)
211 (foreign-bool compression)
212 (or compression 0)
213 #!+win32
214 (ecase application-type
215 (:console 0)
216 (:gui 1))
217 #!-win32 0))
218 (without-gcing
219 (save name
220 (get-lisp-obj-address #'restart-lisp)
221 (foreign-bool executable)
222 (foreign-bool save-runtime-options)
223 (foreign-bool compression)
224 (or compression 0)
225 #!+win32
226 (ecase application-type
227 (:console 0)
228 (:gui 1))
229 #!-win32 0)))))
230 ;; Save the restart function into a static symbol, to allow GC-AND-SAVE
231 ;; access to it even after the GC has moved it.
232 #!+gencgc
233 (setf sb!vm::*restart-lisp-function* #'restart-lisp)
234 (cond #!-gencgc
235 (purify
236 (purify :root-structures root-structures
237 :environment-name environment-name)
238 (save-core nil))
240 (save-core t)))
241 ;; Something went very wrong -- reinitialize to have a prayer
242 ;; of being able to report the error.
243 (reinit)
244 (error 'save-error)))
246 (defun deinit ()
247 (call-hooks "save" *save-hooks*)
248 #!+sb-wtimer
249 (itimer-emulation-deinit)
250 (let ((threads (sb!thread:list-all-threads)))
251 (unless (= 1 (length threads))
252 (let* ((interactive (sb!thread::interactive-threads))
253 (other (set-difference threads interactive)))
254 (error 'save-with-multiple-threads-error
255 :interactive-threads interactive
256 :other-threads other))))
257 (float-deinit)
258 (profile-deinit)
259 (foreign-deinit)
260 (stream-deinit)
261 (deinit-finalizers)
262 (drop-all-hash-caches)
263 (os-deinit)
264 (setf * nil ** nil *** nil
265 - nil + nil ++ nil +++ nil
266 /// nil // nil / nil))