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
Throw away more radioactive locks that could be held across a fork in threading.py #50892
Comments
This bug is similar to the importlock deadlock, and it's really part of I've attached a test case that inserts calls to sleep at the right
So there's the deadlock. I think I should be able to fix it just by resetting the condition |
Here's a patch for 3.2 which adds the fix and a test case. I also |
Here's an updated patch for py3k (3.2). The test still fails without the fix, and passes with the fix. Thinking more about this, I'll try summarizing the bug more coherently: When the main thread joins the child threads, it acquires some locks. If a fork in a child thread occurs while those locks are held, they remain locked in the child process. My solution is to do here what we do elsewhere in CPython: abandon radioactive locks and allocate fresh ones. |
I realized that in a later fix for unladen-swallow, we also cleared the condition variable waiters list, since it has radioactive synchronization primitives in it as well. Here's an updated patch that simplifies the fix by just using __init__() to completely reinitialize the condition variables and adds a test. This corresponds to unladen-swallow revisions r799 and r834. |
I don't have any direct opinions on this, as it is just a bandaid. fork, as defined by POSIX, doesn't allow what we do with it, so we're reliant on great deal of OS and library implementation details. The only portable and robust solution would be to replace it with a unified fork-and-exec API that's implemented directly in C. |
I completely agree, but the cat is out of the bag on this one. I don't see how we could get rid of fork until Py4K, and even then I'm sure there will be people who don't want to see it go, and I'd rather not spend my time arguing this point. The only application of fork that doesn't use exec that I've heard of is pre-forked Python servers. But those don't seem like they would be very useful, since with refcounting the copy-on-write behavior doesn't get you very many wins. The problem that this bandaid solves for me is that test_threading.py already tests thread+fork behaviors, and can fail non-deterministically. This problem was exacerbated while I was working on making the compilation thread. I don't think we can un-support fork and threads in the near future either, because subprocess.py uses fork, and libraries can use fork behind the user's back. |
fwiw a unified fork-and-exec API implemented in C is what I added in Modules/_posixsubprocess.c to at least avoid this issue as much as possible when using subprocess. |
patch looks good. committed in r87710 for 3.2. needs back porting to 3.1 and 2.7 and optionally 2.6. |
r87726 for release31-maint |
Attached is a patch for Python 2.6 release26_maint for reference incase someone wants it. That branch is closed - security fixes only. |
r87710 introduces an AttributeError in test_thread's TestForkInThread test case. If os.fork() is called from a thread created by the _thread module, threading._after_fork() will get a _DummyThread (with no _block attribute) as the current thread. I've attached a patch that checks whether the thread has a _block attribute before trying to reinitialize it. |
eek, thanks for noticing that! r87740 fixes this in py3k. backporting to 3.1 and 2.7 now. |
r87741 3.1 |
Python version: 2.7.5 I'm still observing this issue (or bpo-5114) on Solaris 9. The symptom is that test_threading hangs indefinitely (tested: overnight) and running pstack on the process, I'm seeing: ----------------- lwp# 1 / thread# 1 -------------------- The problem does not occur on Solaris 10. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: