Skip to content

multiprocessing.resource_tracker is imported more than once #1306

Open
@finite-state-machine

Description

@finite-state-machine

Describe the bug

The coverage package causes multiprocessing.resource_tracker to be imported more than once, resulting in leaked resources, warnings, and other issues.

To Reproduce

Fairly concise code to reproduce the issue is attached as a tarball, as directory structure matters. The POC depends on pip, pytest, pytest-cov, and pyftpdlib.

The files of the tarball (neglecting the directory that prevents it from being a tarbomb) are as follows:

reproduce_issue.sh

#!/usr/bin/env bash
python3 -m pip install -r requirements.txt
python3 -m pytest --pyargs --cov=some_package.some_module some_package.some_module --capture=no

requirements.txt

pyftpdlib
pytest
pytest-cov

some_package/__init__.py

from . import some_module

some_package/some_module.py

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

Sample output of reproduce_issue.sh (excluding pip's output):

======================================================================================================================================================================================================================================================================= test session starts =======================================================================================================================================================================================================================================================================
platform darwin -- Python 3.8.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/me/coverage_bug
plugins: cov-3.0.0
collected 0 items


---------- coverage: platform darwin, python 3.8.3-final-0 -----------
Name                          Stmts   Miss  Cover
-------------------------------------------------
some_package/some_module.py       3      0   100%
-------------------------------------------------
TOTAL                             3      0   100%

====================================================================================================================================================================================================================================================================== no tests ran in 0.17s ======================================================================================================================================================================================================================================================================
/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py:221: UserWarning: resource_tracker: There appear to be 6 leaked semaphore objects to clean up at shutdown
  warnings.warn('resource_tracker: There appear to be %d '
/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py:234: UserWarning: resource_tracker: '/mp-1lcpmomy': [Errno 22] Invalid argument
  warnings.warn('resource_tracker: %r: %s' % (name, e))
/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py:234: UserWarning: resource_tracker: '/mp-kzffvfiw': [Errno 22] Invalid argument
  warnings.warn('resource_tracker: %r: %s' % (name, e))
/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py:234: UserWarning: resource_tracker: '/mp-fpqvsru6': [Errno 22] Invalid argument
  warnings.warn('resource_tracker: %r: %s' % (name, e))
/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py:234: UserWarning: resource_tracker: '/mp-tytkkqsh': [Errno 22] Invalid argument
  warnings.warn('resource_tracker: %r: %s' % (name, e))
/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py:234: UserWarning: resource_tracker: '/mp-wam1qd25': [Errno 22] Invalid argument
  warnings.warn('resource_tracker: %r: %s' % (name, e))
/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py:234: UserWarning: resource_tracker: '/mp-_qu77dju': [Errno 22] Invalid argument
  warnings.warn('resource_tracker: %r: %s' % (name, e))
rtype='semaphore'
Traceback (most recent call last):
  File "/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py", line 203, in main
    cache[rtype].remove(name)
KeyError: '/mp-kzffvfiw'
rtype='semaphore'
Traceback (most recent call last):
  File "/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py", line 203, in main
    cache[rtype].remove(name)
KeyError: '/mp-fpqvsru6'
rtype='semaphore'
Traceback (most recent call last):
  File "/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py", line 203, in main
    cache[rtype].remove(name)
KeyError: '/mp-wam1qd25'
rtype='semaphore'
Traceback (most recent call last):
  File "/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py", line 203, in main
    cache[rtype].remove(name)
KeyError: '/mp-_qu77dju'
rtype='semaphore'
Traceback (most recent call last):
  File "/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py", line 203, in main
    cache[rtype].remove(name)
KeyError: '/mp-tytkkqsh'
rtype='semaphore'
Traceback (most recent call last):
  File "/Users/me/.pyenv/versions/3.8.3/lib/python3.8/multiprocessing/resource_tracker.py", line 203, in main
    cache[rtype].remove(name)
KeyError: '/mp-1lcpmomy'

Expected behavior
No errors or warnings should be issued when testing this code.

Additional context

The problem seems to happen because of coverage.misc.sys_modules_saved(), which causes the multiprocessing.resource_tracker module to be imported more than once. That module contains a singleton (_resource_tracker/ResourceTracker) responsible for tracking certain objects which can be shared across processes, including multiprocessing.Lock(), which is used by pyftpdlib.

That some_package/__init__.py imports some_package.some_module seems to be important, as does --pyargs.

It may be that excluding multiprocessing.resource_tracker from sys_modules_saved() is sufficient to solve this issue.

I apologize for any deficits in this bug report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions