python / python/cpython

SharedMemory constructor raises "cannot mmap an empty file" exception

Aberta
#92,408 2 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

stdlib topic-multiprocessing type-bug
Linguagem predominante
Python
Estrelas
77.2k
Forks
36k
Merge médio
1d 9h
PRs com merge (30d)
558

Descrição

Bug report

I was trying to clean up a shared memory object left behind by an earlier process using the following code:

shm = SharedMemory("some_name")
shm.close()
shm.unlink()

However, the first line resulted in an exception being raised:

  File "/home/USER/.pyenv/versions/3.9.10/lib/python3.9/multiprocessing/shared_memory.py", line 114, in __init__
    self._mmap = mmap.mmap(self._fd, size)
ValueError: cannot mmap an empty file

The exception handler around that line unlinks the object in case of an OSError, but not in case of this ValueError raised by mmap.mmap:

https://github.com/python/cpython/blob/973a5203c151efb7a86a478140f7b0c9ae70438f/Lib/multiprocessing/shared_memory.py#L109-L117

This makes it effectively impossible to clean up this particular shared memory object through the standard library.

I'm not sure how the shared memory object was corrupted in the first place, but it looks like the exception is triggered because os.fstat states that it has size 0:

>>> f = _posixshmem.shm_open('some_name', os.O_RDWR, mode=0o600)
>>> os.fstat(f)
os.stat_result(st_mode=33152, st_ino=80, st_dev=27, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=1651836036, st_mtime=1651836036, st_ctime=1651836036)

After which the code tries to mmap with size 0 and fails with the exception mentioned earlier.

I was only able to resolve this by calling _posixshmem.shm_unlink('some_name') manually. I think the exception handler should be extended to also unlink the file if it was truncated to 0 like this.

This scenario can be reproduced with the following code:

import _posixshmem
import os
from multiprocessing.shared_memory import SharedMemory

f = _posixshmem.shm_open('test', os.O_RDWR | os.O_CREAT | os.O_EXCL, 0o600)
os.close(f)

try:
    mem = SharedMemory("test")
finally:
    _posixshmem.shm_unlink("test")

Your environment

  • CPython versions tested on: 3.9.10
  • Operating system and architecture: Ubuntu 20.04.3 LTS
Linked PRs
  • gh-133227

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece em Lib/multiprocessing/shared_memory.py, no construtor de SharedMemory, e revise o caminho de exceção em torno de mmap.mmap. Execute a reprodução mostrada na issue na plataforma afetada e, em seguida, inspecione o PR vinculado gh-133227. O trabalho estará concluído quando um objeto de memória compartilhada de tamanho zero puder ser limpo pelo caminho da biblioteca padrão sem deixar ValueError sem tratamento.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
operating-systems
Tipo de issue
Bug
Dificuldade
3/5
Tempo estimado
1-2 dias
Status de atividade
Estagnada
Clareza
Claramente especificada
Facilidade para iniciantes
35/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.