thing to do.)
changes in sbcl-0.7.9 relative to sbcl-0.7.8:
- * fixed bug: VALUES-LIST is no longer optimized away
+ * minor incompatible change: The runtime (the Unix executable named
+ "sbcl") is now much pickier about the .core files it will load.
+ Essentially it now requires .core files to descend from the same
+ build (not just the same sources or LISP-IMPLEMENTATION-VERSION)
+ as the runtime does. (The intent is to prevent the crashes which
+ can occur, and which can even be reported as mysterious failures,
+ when people patch the sources or change the build parameters
+ without changing LISP-IMPLEMENTATION-VERSION, then mix and match
+ sbcl and .core files.)
+ * fixed bug: VALUES-LIST is no longer optimized away.
* fixed bug 142: The FFI conversion of C string values to Lisp
string values no longer conses excessively. (thanks to Nathan
Froyd porting Raymond Toy's fix to CMU CL)
* improved MOP conformance in PCL (thanks to Nathan Froyd porting
Gerd Moellman's work in CMU CL)
- * fixed bug 202: the compiler failed on a function, which derived
- type contradicted declared.
+ * fixed bug 202: The compiler no longer fails on functions whose
+ derived types contradict their declared type.
planned incompatible changes in 0.7.x:
* When the profiling interface settles down, maybe in 0.7.x, maybe
# and target machines.
sh make-config.sh || exit 1
+# Make a unique ID for this build (to discourage people from
+# mismatching sbcl and *.core files).
+echo '"'`hostname -s`-`whoami`-`date +%F-%H-%M-%S`'"' > output/build-id.tmp
+
# The make-host-*.sh scripts are run on the cross-compilation host,
# and the make-target-*.sh scripts are run on the target machine. In
# ordinary compilation, we just do these phases consecutively on the
"SB!EXT" "SB!INT" "SB!KERNEL" "SB!SYS")
:export ("*ASSEMBLER-ROUTINES*"
"+BACKEND-FASL-FILE-IMPLEMENTATION+"
+ "BUILD-ID-CORE-ENTRY-TYPE-CODE"
"*FASL-FILE-TYPE*"
"CLOSE-FASL-OUTPUT"
"DUMP-ASSEMBLER-ROUTINES"
(root-structures ())
(environment-name "auxiliary"))
#!+sb-doc
- "Saves a CMU Common Lisp core image in the file of the specified name,
- killing the current Lisp invocation in the process (unless it bails
- out early because of some argument error or something).
+ "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.
- The following &KEY args are defined:
+ 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.
+ * 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.
+
+ 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
;;; way to do this in high level data like this (as opposed to e.g. in
;;; IP packets), and in fact the CMU CL version number never ended up
;;; being incremented past 0. A better approach might be to use a
-;;; string which is set from CVS data.
+;;; string which is set from CVS data. (Though now as of sbcl-0.7.8 or
+;;; so, we have another problem that the core incompatibility
+;;; detection mechanisms are on such a hair trigger -- with even
+;;; different builds from the same sources being considered
+;;; incompatible -- that any coarser-grained versioning mechanisms
+;;; like this are largely irrelevant as long as the hair-triggering
+;;; persists.)
;;;
;;; 0: inherited from CMU CL
;;; 1: rearranged static symbols for sbcl-0.6.8
;;; 2: eliminated non-ANSI %DEFCONSTANT/%%DEFCONSTANT support,
;;; deleted a slot from DEBUG-SOURCE structure
-(defconstant sbcl-core-version-integer 2)
+;;; 3: added build ID to cores to discourage sbcl/.core mismatch
+(defconstant sbcl-core-version-integer 3)
(defun round-up (number size)
#!+sb-doc
(defvar *core-file*)
(defvar *data-page*)
+;;; magic numbers to identify entries in a core file
+;;;
+;;; (In case you were wondering: No, AFAIK there's no special magic about
+;;; these which requires them to be in the 38xx range. They're just
+;;; arbitrary words, tested not for being in a particular range but just
+;;; for equality. However, if you ever need to look at a .core file and
+;;; figure out what's going on, it's slightly convenient that they're
+;;; all in an easily recognizable range, and displacing the range away from
+;;; zero seems likely to reduce the chance that random garbage will be
+;;; misinterpreted as a .core file.)
(defconstant version-core-entry-type-code 3860)
+(defconstant build-id-core-entry-type-code 3899)
(defconstant new-directory-core-entry-type-code 3861)
(defconstant initial-fun-core-entry-type-code 3863)
(defconstant end-core-entry-type-code 3840)
(write-word 3)
(write-word sbcl-core-version-integer)
+ ;; Write the build ID.
+ (write-word build-id-core-entry-type-code)
+ (let ((build-id (with-open-file (s "output/build-id.tmp"
+ :direction :input)
+ (read s))))
+ (declare (type simple-string build-id))
+ (/show build-id (length build-id))
+ ;; Write length of build ID record: BUILD-ID-CORE-ENTRY-TYPE-CODE
+ ;; word, this length word, and one word for each char of BUILD-ID.
+ (write-word (+ 2 (length build-id)))
+ (dovector (char build-id)
+ ;; (We write each character as a word in order to avoid
+ ;; having to think about word alignment issues in the
+ ;; sbcl-0.7.8 version of coreparse.c.)
+ (write-word (char-code char))))
+
;; Write the New Directory entry header.
(write-word new-directory-core-entry-type-code)
(write-word 17) ; length = (5 words/space) * 3 spaces + 2 for header.
extern lispobj load_core_file(char *file);
+/* arbitrary string identifying this build, embedded in .core files to
+ * prevent people mismatching a runtime built e.g. with :SB-SHOW
+ * against a .core built without :SB-SHOW (or against various grosser
+ * mismatches, e.g. a .core built with an old version of the code
+ * against a runtime with patches which add new C code) */
+extern unsigned char build_id[];
+
#endif
#include "interr.h"
#include "sbcl.h"
+unsigned char build_id[] =
+#include "../../output/build-id.tmp"
+;
+
static void
process_directory(int fd, u32 *ptr, int count)
{
}
break;
+ case BUILD_ID_CORE_ENTRY_TYPE_CODE:
+ SHOW("BUILD_ID_CORE_ENTRY_TYPE_CODE case");
+ {
+ int i;
+
+ FSHOW((stderr, "build_id[]=\"%s\"\n", build_id));
+ FSHOW((stderr, "remaining_len = %d\n", remaining_len));
+ if (remaining_len != strlen(build_id))
+ goto losing_build_id;
+ for (i = 0; i < remaining_len; ++i) {
+ FSHOW((stderr, "ptr[%d] = char = %d, expected=%d\n",
+ ptr[i], i, build_id[i]));
+ if (ptr[i] != build_id[i])
+ goto losing_build_id;
+ }
+ break;
+ losing_build_id:
+ /* .core files are not binary-compatible between
+ * builds because we can't easily detect whether the
+ * sources were patched between the time the
+ * dumping-the-.core runtime was built and the time
+ * that the loading-the-.core runtime was built.
+ *
+ * (We could easily detect whether version.lisp-expr
+ * was changed, but people experimenting with patches
+ * don't necessarily update version.lisp-expr.) */
+
+ lose("can't load .core for different runtime, sorry");
+ }
+
case NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE:
SHOW("NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE case");
process_directory(fd,
printf("done]\n");
fflush(stdout);
- /* (Now we can actually start copying ourselves into the
- * output file.) */
+ /* (Now we can actually start copying ourselves into the output file.) */
printf("[saving current Lisp image into %s:\n", filename);
fflush(stdout);
putw(3, file);
putw(SBCL_CORE_VERSION_INTEGER, file);
- putw(NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE, file);
- putw((5*3)+2, file);
+ putw(BUILD_ID_CORE_ENTRY_TYPE_CODE, file);
+ putw(/* (We're writing the word count of the entry here, and the 2
+ * term is one word for the leading BUILD_ID_CORE_ENTRY_TYPE_CODE
+ * word and one word where we store the count itself.) */
+ 2 + strlen(build_id),
+ file);
+ {
+ char *p;
+ for (p = build_id; *p; ++p)
+ putw(*p, file);
+ }
+ putw(NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE, file);
+ putw(/* (word count = 3 spaces described by 5 words each, plus the
+ * entry type code, plus this count itself) */
+ (5*3)+2, file);
output_space(file,
READ_ONLY_CORE_SPACE_ID,
(lispobj *)READ_ONLY_SPACE_START,
;;; internal versions off the main CVS branch, it gets hairier, e.g.
;;; "0.pre7.14.flaky4.13".)
-"0.7.8.11"
+"0.7.8.12"