-
-
Notifications
You must be signed in to change notification settings - Fork 31.1k
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
gh-127421: Fix race in test_start_new_thread_failed #127549
Conversation
When we succeed in starting a new thread, for example if setrlimit was ineffective, we must wait for the newly spawned thread to exit. Otherwise, we run the risk that the newly spawned thread will race with runtime finalization and access memory that has already been clobbered/freed. `_thread.start_new_thread()` only spawns daemon threads, which the runtime does not wait for at shutdown, and does not return a handle. Use `_thread.start_joinable_thread()` and join the resulting handle when the thread is started successfully.
I was able to reproduce the failure on my macbook pro. With the fix in this PR I was unable to reproduce the failure when running:
|
Are you sure that the original issue, the fix of which is tested here, was reproducible with |
I can reproduce the original issue with |
Does this need to be backported? |
Yes, I can reproduce the issue in 3.13 and 3.12 as well. |
Ok, 3.12 will need a different fix, because |
Thanks @mpage for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13. |
…27549) Fix race in test_start_new_thread_failed When we succeed in starting a new thread, for example if setrlimit was ineffective, we must wait for the newly spawned thread to exit. Otherwise, we run the risk that the newly spawned thread will race with runtime finalization and access memory that has already been clobbered/freed. `_thread.start_new_thread()` only spawns daemon threads, which the runtime does not wait for at shutdown, and does not return a handle. Use `_thread.start_joinable_thread()` and join the resulting handle when the thread is started successfully. (cherry picked from commit 13b68e1) Co-authored-by: mpage <[email protected]>
GH-127574 is a backport of this pull request to the 3.13 branch. |
#127574) gh-127421: Fix race in test_start_new_thread_failed (GH-127549) Fix race in test_start_new_thread_failed When we succeed in starting a new thread, for example if setrlimit was ineffective, we must wait for the newly spawned thread to exit. Otherwise, we run the risk that the newly spawned thread will race with runtime finalization and access memory that has already been clobbered/freed. `_thread.start_new_thread()` only spawns daemon threads, which the runtime does not wait for at shutdown, and does not return a handle. Use `_thread.start_joinable_thread()` and join the resulting handle when the thread is started successfully. (cherry picked from commit 13b68e1) Co-authored-by: mpage <[email protected]>
|
The buildbot failure looks unrelated to this change. |
) Fix race in test_start_new_thread_failed When we succeed in starting a new thread, for example if setrlimit was ineffective, we must wait for the newly spawned thread to exit. Otherwise, we run the risk that the newly spawned thread will race with runtime finalization and access memory that has already been clobbered/freed. `_thread.start_new_thread()` only spawns daemon threads, which the runtime does not wait for at shutdown, and does not return a handle. Use `_thread.start_joinable_thread()` and join the resulting handle when the thread is started successfully.
) Fix race in test_start_new_thread_failed When we succeed in starting a new thread, for example if setrlimit was ineffective, we must wait for the newly spawned thread to exit. Otherwise, we run the risk that the newly spawned thread will race with runtime finalization and access memory that has already been clobbered/freed. `_thread.start_new_thread()` only spawns daemon threads, which the runtime does not wait for at shutdown, and does not return a handle. Use `_thread.start_joinable_thread()` and join the resulting handle when the thread is started successfully.
When we succeed in starting a new thread, for example if setrlimit was ineffective, we must wait for the newly spawned thread to exit. Otherwise, we run the risk that the newly spawned thread will race with runtime finalization and access memory that has already been freed. In this case, this assertion tends to fire:
cpython/Python/pystate.c
Line 322 in dffb909
when the newly created thread attempts to bind the state after the runtime has been finalized, because all thread states are cleared and deleted as part of finalization.
The use of
_thread.start_new_thread()
is problematic here. It only spawns daemon threads, which the runtime does not wait for during finalization, and does not return a joinable handle. Instead, use_thread.start_joinable_thread()
and join the resulting handle when the thread is started successfully.test_start_new_thread_failed
flaky: failed on macOS (free threading) #127421