Subject: bug#17168: 24.3.50; Segfault at mark_object

From: Stefan Monnier <[email-masked]>
Date: Thu, 03 Apr 2014 11:42:54 -0400

> What about this workaround? Until we find a better solution,
> this should prevent crashes at least.

Let's try to find a better fix instead of another workaround around the
existing workaround.

So the existing workaround is here:

	    /* Check if the symbol was created during loadup.  In such a case
	       it might be pointed to by pure bytecode which we don't trace,
	       so we conservatively assume that it is live.  */
	    bool pure_p = PURE_POINTER_P (XSTRING (sym->s.name));

	    if (!sym->s.gcmarkbit && !pure_p)
	      {
		if (sym->s.redirect == SYMBOL_LOCALIZED)
		  xfree (SYMBOL_BLV (&sym->s));
		sym->s.next = symbol_free_list;
		symbol_free_list = &sym->s;
#if GC_MARK_STACK
		symbol_free_list->function = Vdead;
#endif
		++this_free;
	      }
	    else
	      {
		++num_used;
		if (!pure_p)
		  eassert (!STRING_MARKED_P (XSTRING (sym->s.name)));
		sym->s.gcmarkbit = 0;
	      }

I.e. any symbol with a pure name is assumed to be potentially reachable
from some pure objects.  But not only this assumption is wrong, but its
implementation is wrong as well: we just keep the symbol without making
sure we also keep the objects it points to.

Furthermore, in theory some pure object may very well point to a symbol
whose name was not made pure.  Worse, a pure object may point to several
other kinds of non-pure objects, so this special treatment we have for
symbols should really be applied to other "non-purifyable" objects.

How 'bout we change `purecopy' such that before doing

    /* Not purified, don't hash-cons.  */
    return obj;

it adds the object to a table of "objects pointed from pure space"?

This table should probably be a hash-table (for simplicity), and of
course we'd only add objects to it when the purecopy call was
a recursive call, not for toplevel calls (i.e. calling (purecopy
<process>) should not add <process> to the table since it's not pointed
to from a pure object, whereas (purecopy '(<process>)) should).

        Stefan