Hi Olivier, Olivier Dion <olivier.d...@polymtl.ca> skribis:
> From: Olivier Dion <olivier-d...@proton.me> > > When calling `environ', Guile set the global variable `environ' to a > list allocated with the GC. Strings in it are also allocated with the > GC. > > However, if an user call the Scheme setenv() procedure, the resulting > call to putenv() in libc might reallocate `environ' to a new pointer > while copying sub-pointers owned by Guile in it. > > This results in the GC marking these strings for reclamation when they > are actually still present in `environ'. Thus, the values in the > environment are now undefined. > > To fix this, Guile should only manipulate the `environ' using the > standard libc functions. This ensures that concurrent modification of > it is safe in multi-threaded program. Therefore, the procedure > `environ' now call the libc clearenv() procedure to purge the > environment. Then, the desired values are put in `environ' using > scm_putenv(). At the end, no GC allocated memory is put in `environ'. > > Also, since `environ' can be changed at anytime in a multi-thread > program, emit a warning stipulating that the result is undefined > behavior if multiple threads are created in the program. Consider for > example a thread iterating over `environ' while another one do a call to > putenv(). The latter would do a realloc() on `environ' and thus the old > array read by the former now contains garbage. > > On system where clearenv() is not present, an atomic store of NULL with > sequential consistency to `environ' should be sufficient but see the > NOTES of clearenv(3). > > * libguile/posix.c (scm_environ): Do not store GC allocated memory in > environ. Thanks for the clear explanation and patch. Finally applied with an added comment in the code. Ludo’.