On 10/13/26 10:59 PM, Andre Vehreschild wrote:
Hi Jerry,
thanks for taking over the coarray stuff.
About unlinking the shared segment: Keeping the file existing and usable after
unlink is a Linux special. Other OS do not support this (when I am not mistaken
all of the BSD family removes the file). I fell for that, so you might want to
branch OS dependent here.
Keep on the work,
Andre
Hi Andre,
Thanks for looking at it. As far as I can tell the patch only relies
on what POSIX requirements of shm_unlink: "If one or more references to
the shared memory object exist when the object is unlinked, the name
shall be removed before shm_unlink() returns, but the removal of the
memory object contents shall be postponed until all open and map
references to the shared memory object have been removed."
What does break everywhere is opening the object by name after the
unlink, which is what the images do now. With the patch they no
longer do that: the supervisor clears FD_CLOEXEC, passes the
descriptor number in GFORTRAN_SHMEM_FD, and the images mmap the
inherited descriptor. If clearing FD_CLOEXEC fails, or there is no
setenv, the name is kept and the old shm_open path is used.
Do you remember which system you hit it on? If there is one where an
inherited descriptor does not work, I can limit the unlink to Linux like this:
#if defined(HAVE_SETENV) && defined(__linux__)
/* Pass the descriptor to the images and remove the name, so that the
object goes away with the last process however the program ends.
Only Linux is known to keep an unlinked object usable. */
if (fcntl (mem->shm_fd, F_SETFD, 0) == 0)
{
char val[20];
snprintf (val, 20, "%d", mem->shm_fd);
setenv (ENV_FD, val, 1);
shm_unlink (shm_name);
}
#endif
I know Steve uses FreeBSD, maybe he can test this on that system to
see what it does.
Regards,
Jerry
On Tue, 13 Oct 2026 12:09:59 -0700
Jerry DeLisle <[email protected]> wrote:
See attached patch. The supervisor created the shared memory object
with shm_open and unlinked it only on a normal exit, so when it was
stopped by a signal (a testsuite timeout, ^C) the object stayed in
/dev/shm. The fix passes the open descriptor to the images in
GFORTRAN_SHMEM_FD and unlinks the name right after the object is sized,
so the kernel frees it when the last process closes it, however the
program ends.
All of it is in shared_memory_init and shared_memory_cleanup in
shared_memory.c. In the supervisor branch, clearing FD_CLOEXEC keeps
the descriptor across the execve of the images; if that fails the
name is kept and the old shm_open path is used. The image branch takes
the descriptor from the environment. MADV_DONTDUMP is needed because
the kernel dumps an unlinked object like anonymous memory: without it
an image that aborts writes the whole pool into its core file.
shared_memory_cleanup skips shm_unlink when the name is already gone.
The code is under HAVE_SETENV, so other targets are unchanged.
There is no test, since it needs a signal sent to the program. By
hand: a program that never ends, run under "timeout 2", leaves no
/dev/shm/gfor-shm-* behind. A signal sent to the supervisor's pid alone
still leaves the images running, because the supervisor has no signal
handler; that is a separate, older problem, and with this patch the
object goes away once those images are killed.
Regression tested on x86_64.
OK for mainline?
Regards,
Jerry
---
libgfortran: [PR127753] caf_shmem: do not leak the shared memory object
When the supervisor was stopped by a signal, for example by a timeout or
^C, it exited without unlinking the shared memory object, so the object
was left behind in /dev/shm.
The supervisor now passes the descriptor of the object to the images and
removes its name right after creating it, so that the object goes away
with the last process however the program ends. The mapping is excluded
from core dumps, because the kernel dumps an unlinked object like
anonymous memory, which would write out the whole pool.
Assisted-by: Claude Opus 5.5
PR libfortran/127753
libgfortran/ChangeLog:
* caf/shmem/shared_memory.c (ENV_FD): New.
(shared_memory_init): Pass the descriptor to the images through
ENV_FD and unlink the object. Use the inherited descriptor in an
image. Exclude the mapping from core dumps.
(shared_memory_cleanup): Do not unlink an unlinked object.