-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
test_multiprocessing_forkserver.test_processes: ResourceTracker.ensure_running() calls itself and hangs indirectly via the GC #109593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
cc @pitrou |
A reentrant lock would probably fix the hang, but it wouldn't make the code correct against reentrancy... |
What we need is a lock that is reentrant and tells us that we've entered a reentrant call. |
multiprocessing: Reduce the risk of reentrant calls to ResourceTracker.ensure_running() by running explicitly all finalizers before acquiring the ResourceTracker lock.
Right, I agree.
Sure, something like that would be doable, but it looks a little bit complicated. I came up with a simpler approach: run explicitly all finalizers before acquiring the lock: PR #109620. |
Script to trigger the bug: import multiprocessing
import multiprocessing.synchronize
import multiprocessing.resource_tracker
import faulthandler
import gc
# Try values from 1 to 10 to trigger the bug
GC_THRESHOLD = 3
# spawn uses SemLock._cleanup()
ctx = multiprocessing.get_context('spawn')
faulthandler.dump_traceback_later(10, exit=True)
class RefCycle:
pass
if 1:
# Create a lock which will register its SemLock._cleanup() function
# in util._finalizer_registry. This _cleanup() will be called
# indirectly by the garbage collector.
sem = multiprocessing.synchronize.Semaphore(ctx=ctx)
cycle = RefCycle()
cycle.cycle = cycle
cycle.sem = sem
sem = None
cycle = None
# Start the process
print("ensure_running")
gc.set_threshold(GC_THRESHOLD)
multiprocessing.resource_tracker.ensure_running()
print("ensure_running--")
gc.collect()
# Stop explicitly the process
print("stop resource tracker")
multiprocessing.resource_tracker._resource_tracker._stop()
print("exit") |
multiprocessing: Reduce the risk of reentrant calls to ResourceTracker.ensure_running() by running explicitly a garbage collection, to call pending finalizers, before acquiring the ResourceTracker lock.
multiprocessing: Reduce the risk of reentrant calls to ResourceTracker.ensure_running() by running explicitly a garbage collection, to call pending finalizers, before acquiring the ResourceTracker lock.
Another failure on x86-64 macOS 3.x: https://buildbot.python.org/all/#/builders/366/builds/5426 |
…109629) --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
…cker (pythonGH-109629) --------- (cherry picked from commit 0eb9883) Co-authored-by: Antoine Pitrou <[email protected]> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
…cker (pythonGH-109629) --------- (cherry picked from commit 0eb9883) Co-authored-by: Antoine Pitrou <[email protected]> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
…cker (python#109629) --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
This has been fixed in #109629 and backported to 3.12 and 3.11. |
…cker (python#109629) --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
PPC64LE Fedora Stable Refleaks 3.x: test_wrapped_exception() of test_multiprocessing_forkserver.test_processes hanged while calling SemLock._cleanup():
It seems like there is a reentrant call to multiprocessing ResourceTracker.ensure_running():
Sadly, ensure_running() is not reentrant, on purpose, there is a lock.
Traceback:
Logs:
build: https://buildbot.python.org/all/#/builders/280/builds/824
Linked PRs
The text was updated successfully, but these errors were encountered: