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

From: Gerd Möllmann <[email-masked]>
Date: Sat, 04 Jan 2025 09:58:56 +0100

Eli Zaretskii <[email-masked]> writes:

>> From: Gerd Möllmann <[email-masked]>
>> Cc: [email-masked],  [email-masked], Helmut Eller
>>  <[email-masked]>
>> Date: Sat, 04 Jan 2025 08:17:34 +0100
>> 
>> Eli Zaretskii <[email-masked]> writes:
>> 
>> > The current code in callproc.c assumes that GC cannot run while we are
>> > parked in posix_spawn or vfork.  Is that assumption false with MPS?
>> > If so, what would trigger GC during that time?
>> 
>> Okay, so it's safe with the old GC, I assume. Do you know if it is done
>> with an inhibit_garbage_collection?
>
> No, without.  Unless posix_spawn could somehow call back to us in a
> way that posix_spawn will later return and resume running (as opposed
> to via a fatal signal), how could GC happen?
>
>> Not that we run into the trap that somewhere on the way to the
>> actual fork maybe_quit is called which can GC and so on, like we had
>> it in the regexp engine a while back.
>
> This can be established by examining the code, right?

In principle yes, one could check if maybe_quit is called in the call
trees between the point SDATA is stored and fork happens, but I wouldn't
do it because (1) someone might add a maybe_quit at some point, (2)
Pip's solution is immune to the problem, and (3) it's potentially a lot
of work to figure out if GC can be called in a call tree.

>> For MPS, I don't know for sure. I have seen in passing while git
>> grepping in their repo recently, that they write something about forking
>> and child processes, but I don't know what they do. Maybe someone having
>> read the code can answer that. (Added Helmut in CC).
>
> We are talking about vfork, not fork.  In our case, the forked process
> runs a completely separate program, in most cases not even Emacs, so MPS
> has no bearing on that, I think.

Okay. I hope Helmut and/or Pip know more about this than I do.

>> > Another question is about the global Lisp variables in 'globals'.  For
>> > example, Vprocess_environment actually globals.f_Vprocess_environment.
>> > Is this large struct protected from GC, i.e. can GC ever decide that
>> > process-environment is not used and free it?  If it's protected, where
>> > and how is it protected?  And if it is protected, then any members of
>> > the list that is the value of process-environment are also protected
>> > and cannot be freed by GC.
>> >
>> > If 'globals' is not protected, I think we should protect it, no?
>> 
>> process-environment is a DEFVAR_LISP, and is root in both GCs via the
>> staticpro mechanism (staticvec array).
>
> OK, so it's impossible that some member of the process-environment's
> list will be GCed, right?  

Right.

> AFAIU, Pip was considering a situation where some of these member
> strings are GCed, and then subroutines of posix_spawn use a bad
> address, to explain the error message Ihor reported. This seems
> impossible because process-environment is staticpro'd, right?

I think that scenario cannot happen in this case, right. I'd like his
xstrdups better anyway, so that all becomes irrelevant for both GCs.
Less to worry about :-).