Subject: Re: bug#75322: SAFE_ALLOCA assumed to root Lisp_Objects/SSDATA(string)

From: Pip Cet <[email-masked]>
Date: Sun, 05 Jan 2025 11:21:17 +0000

Gerd Möllmann <[email-masked]> writes:

> Eli Zaretskii <[email-masked]> writes:
>> MAX_ALLOCA is only 16KB (and Paul Eggert says it's dangerous to make
>> it significantly larger), so I'm not sure your assumption about
>> negligible performance impact is necessarily correct.
>
> Works well for me so far.

Paul, this discussion is about changing SAFE_ALLOCA so its memory area
is scanned conservatively for the scratch/igc branch, even if xmalloc is
used (when there isn't enough stack space).

MPS requires this in some cases where the old GC didn't, because it's
enough for the old GC that we know there is a reference to retained
objects elsewhere, but MPS might move the data in that case.

However, given how rare it is for SAFE_ALLOCA to use xmalloc, maybe it
would be a good idea to make the corresponding change for the old GC,
too?

Also, scratch/igc behaves differently with regard to SDATA: references
to string data will keep the string data (but not its metadata) alive.
If scratch/igc is ever merged and people start using it exclusively, we
may start seeing bugs that rely on this additional safety guarantee.

My preference would be to change the traditional GC to also ensure code
like

  char *p = SDATA (string);
  string = Qnil;
  garbage_collect ();
  puts (p);

is safe.  Some memory and performance cost, but no-GC assumptions are
hard to verify.  This may or may not fix bugs in the present code.

A potential example for such a bug is this:

I think that it's possible for call_process to call Lisp via ENCODE_FILE
in a very unusual scenario, which might trigger GC and relocation of
string data which has already been put in the argv and environment
arrays.

However, I don't fully understand which additional protections
traditional GC offers: is it always unsafe to use an SDATA obtained
before a GC run after the GC run completes, or is there a more
complicated set of rules?

Pip