[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

GC/EVAL bug



(defun (foo macro) (())
  (let ((sym (gensym)))
    `((lambda (,sym) (print ,sym) (gc))
      6)))

(*rset () )		;So no EVALFRAMEs
(GC)			;To make the only garbage what we're about to cons
(FOO)
6
NIL
^Z
FFVC/ & (NIL . UNBOUND)

What is going on is this:  The GC does not mark symbols who's value cells
are on the SPECPDL.  Neither does applying a LAMBDA with *RSET set to ()
save the lambda or binding-list on the REGPDL.  And PROGN evaluation doesn't
save old clauses, either, so when you get to the GC, there isn't anybody
pointing to the gensym anymore.  It gets collected.  Later, we unbind
the SPECPDL, and viola!, the freelist is bashed.  The next SETQ of a symbol
without a value cell will result in the symbol UNBOUND being bashed.  Lossage
will propogate.

I don't feel up to figuring out the LAMBDA application code right now
to fix this.  The right fix, of course, is for the GC to protect symbols
pointed to by the SPECPDL, but I guess this isn't feasible.  Second choice
is to make lambda-binding keep a copy of the LAMBDA list on the stack until
after the UNBIND.