python / python/cpython

multiprocessing SharedMemory.__del__ can fail, leak file descriptor

Abierto
#155,003 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

stdlib topic-multiprocessing type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Bug report

Bug description:

When a SharedMemory object goes out of scope, its __del__ method calls self.close() to clean it up. This can break if there is still a buffer exported from its mmap instance. It tries to close the mmap before the fd, so in this case it will leave the file descriptor open:

>>> from multiprocessing.shared_memory import SharedMemory
>>> import os
>>> def shview(size=4096):
...     shmem = SharedMemory(create=True, size=size)
...     print("fd is:", shmem._fd)
...     return shmem.buf.cast('i')
...     
>>> mv = shview()
fd is: 5
Exception ignored while calling deallocator <function SharedMemory.__del__ at 0x7f686264d640>:
Traceback (most recent call last):
  File "/usr/lib64/python3.14/multiprocessing/shared_memory.py", line 189, in __del__
    self.close()
  File "/usr/lib64/python3.14/multiprocessing/shared_memory.py", line 232, in close
    self._mmap.close()
BufferError: cannot close exported pointers exist
>>> os.fstat(5).st_size  # fd still open
4096

I think a better option for __del__ would be to close the fd and leave the mmap & buf objects alone, to be cleaned up as normal by reference counting or GC:

>>> class SharedMemoryFix(SharedMemory):
...     def __del__(self):
...         if self._fd >= 0:
...             os.close(self._fd)
...             self._fd = -1
...             
>>> def shview(size=4096):
...     shmem = SharedMemoryFix(create=True, size=size)
...     print("fd is:", shmem._fd)
...     return shmem.buf.cast('i')
...     
>>> mv = shview()
fd is: 7
>>> os.fstat(7)
Traceback (most recent call last):
  File "<python-input-8>", line 1, in <module>
    os.fstat(7)
    ~~~~~~~~^^^
OSError: [Errno 9] Bad file descriptor

(I'm thinking about the POSIX side here. IDK if the behaviour on Windows needs to be different, though I guess it can rely on the mmap's dealloc too)

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Linked PRs
  • gh-155007
  • gh-155070

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza en Lib/multiprocessing/shared_memory.py, en SharedMemory.del y close(), usando la reproducción en Linux del issue para observar el fallo al exportar el búfer y el descriptor de archivo filtrado. Revisa las PR enlazadas gh-155007 y gh-155070 antes de comenzar; el trabajo estará terminado cuando el destructor ya no deje abierto el descriptor, preservando al mismo tiempo el comportamiento relevante de mmap y del búfer.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
operating-systems
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.