0.7.8.12:
authorWilliam Harold Newman <william.newman@airmail.net>
Wed, 2 Oct 2002 23:22:47 +0000 (23:22 +0000)
committerWilliam Harold Newman <william.newman@airmail.net>
Wed, 2 Oct 2002 23:22:47 +0000 (23:22 +0000)
added build id to .core files to try to discourage .core/sbcl
mismatch adventures

NEWS
make.sh
package-data-list.lisp-expr
src/code/save.lisp
src/compiler/generic/genesis.lisp
src/runtime/core.h
src/runtime/coreparse.c
src/runtime/save.c
version.lisp-expr

diff --git a/NEWS b/NEWS
index e470949..5eab745 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1298,14 +1298,23 @@ changes in sbcl-0.7.8 relative to sbcl-0.7.7:
     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
diff --git a/make.sh b/make.sh
index 6aa8f99..500f56f 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -65,6 +65,10 @@ echo //SBCL_XC_HOST=\"$SBCL_XC_HOST\"
 # 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
index 5639584..20b0950 100644 (file)
@@ -462,6 +462,7 @@ like *STACK-TOP-HINT* and unsupported stuff like *TRACED-FUN-LIST*."
           "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"
index cf3eeff..2356255 100644 (file)
                                         (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
index 4bff913..54c0730 100644 (file)
 ;;; 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
@@ -2922,7 +2929,18 @@ initially undefined function references:~2%")
 (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)
@@ -3017,6 +3035,22 @@ initially undefined function references:~2%")
       (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.
index 385d8a6..aa57ba9 100644 (file)
@@ -32,4 +32,11 @@ struct ndir_entry {
 
 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
index b9bcddb..a00438c 100644 (file)
 #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)
 {
@@ -172,6 +176,36 @@ load_core_file(char *file)
            }
            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,
index 4fd98e7..da73349 100644 (file)
@@ -102,8 +102,7 @@ save(char *filename, lispobj init_function)
     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);
@@ -114,9 +113,22 @@ save(char *filename, lispobj init_function)
     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,
index c2f7b61..d7e5823 100644 (file)
@@ -18,4 +18,4 @@
 ;;; 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"