There was a weird bug in the GC system. The image-writing code causes a

GC to assemble a compacted heap image in newspace which it then writes out
to disk. Then the VM calls ABORT-GC to cancel the GC operation, which scans
the current space, fixing up the "broken hearts" -- restoring word 1 of
each structure that got clobbered with a forwarding pointer.

Unfortunately, someone (possibly myself) had inserted a post_gc_fdports() call
into the VM between the gc and the abort. This procedure updates a C vector of
Scheme values (fdports[]) by following forwarding pointers -- BUT -- in this
instance we didn't really want to break hearts, and the abort-gc code didn't
know about the fdports[] vector, so it couldn't undo the effects. This caused
the fdports[] vec to point into hyperspace after the image dump, and *that*
meant on the next GC, all the live ports were considered dead. Oops.

The fix was to remove this bogus call. The post_gc_fdports() proc is now
called only after a *real* GC.
    -Olin
This commit is contained in:
shivers 1995-10-29 15:45:22 +00:00
parent 579ee12924
commit 00af71f77d
2 changed files with 12 additions and 6 deletions

View File

@ -3480,7 +3480,14 @@ long Tinterpret()
RSstackS = SstackS;
RScode_pointerS = Scode_pointerS;
RSenvS = SenvS;
post_gc_fdports(); /* Hack for scsh's i/o system. Olin. */
/* Do NOT put a call to the scsh I/O gc hook post_gc_fdports() here.
** This GC is not for real -- it's for writing images, and will be
** aborted. But the part of post_gc_fdports that updates the fdports[]
** elements to point into new-space *won't* be aborted, and oops, we're
** pointing into hyperspace. This whole thing is a mess; we need to port
** to a newer Scheme 48 release that gives us structured GC hooks.
** -Olin
*/
close_untraced_portsB_return_tag = 0;
goto close_untraced_portsB;
close_untraced_portsB_return_0:

View File

@ -301,17 +301,16 @@ void post_gc_fdports(void)
{
int fd;
#if 0
#ifdef NOISY_FDGC
fputs("{GC", stderr); fflush(stderr);
#endif
for(fd=0; fd<NUM_FDPORTS; fd++) {
scheme_value port = fdports[fd];
if(STOBP(port)) {
long header = STOB_HEADER(port);
if(STOBP(header)) {
#if 0
#ifdef NOISY_FDGC
fprintf(stderr, "Copying port[fd] %d[%d] header %d\n",
port, fd, header);
fflush(stderr);
@ -324,7 +323,7 @@ void post_gc_fdports(void)
/* Port wasn't copied -- is garbage.
If fd unrevealed, close it. */
int rev = EXTRACT_FIXNUM(*PortRev(port));
#if 0
#ifdef NOISY_FDGC
fprintf(stderr, "GC'ing %srevealed port[fd] %d[%d]\n",
rev == 0 ? "un" : "",
port, fd);
@ -335,7 +334,7 @@ void post_gc_fdports(void)
}
}
}
#if 0
#ifdef NOISY_FDGC
fputs("}", stderr); fflush(stderr);
#endif
}