Skip to content
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

bpo-39776: Lock ++interp->tstate_next_unique_id. (GH-18746) #18746

Merged
merged 2 commits into from
Mar 2, 2020
Merged

bpo-39776: Lock ++interp->tstate_next_unique_id. (GH-18746) #18746

merged 2 commits into from
Mar 2, 2020

Conversation

skrah
Copy link
Contributor

@skrah skrah commented Mar 2, 2020

  • Threads created by PyGILState_Ensure() could have a duplicate tstate->id.

https://bugs.python.org/issue39776

  - Threads created by PyGILState_Ensure() could have a duplicate tstate->id.
@skrah skrah changed the title bpo-39776: Lock ++interp->tstate_next_unique_id. bpo-39776: Lock ++interp->tstate_next_unique_id. (GH-18746) Mar 2, 2020
@vstinner
Copy link
Member

vstinner commented Mar 2, 2020

Oh. That's an interesting bug :-) Would you mind to add a NEWS entry?

The fix should be backported to 3.7 and 3.8 branches. It's a severe bug, likely very hard to reproduce :-(

@codecov
Copy link

codecov bot commented Mar 2, 2020

Codecov Report

Merging #18746 into master will increase coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master   #18746   +/-   ##
=======================================
  Coverage   82.13%   82.14%           
=======================================
  Files        1956     1956           
  Lines      590161   590206   +45     
  Branches    44493    44503   +10     
=======================================
+ Hits       484758   484798   +40     
  Misses      95751    95751           
- Partials     9652     9657    +5     
Impacted Files Coverage Δ
Lib/idlelib/runscript.py 19.23% <0.00%> (-1.54%) ⬇️
Lib/test/test_asyncio/functional.py 70.27% <0.00%> (-1.09%) ⬇️
Python/context.c 80.16% <0.00%> (-1.01%) ⬇️
Modules/selectmodule.c 83.53% <0.00%> (-1.00%) ⬇️
Lib/test/test_asyncio/test_sock_lowlevel.py 89.08% <0.00%> (-0.88%) ⬇️
Lib/filecmp.py 64.81% <0.00%> (-0.62%) ⬇️
Lib/test/test_asyncio/utils.py 87.39% <0.00%> (-0.57%) ⬇️
Lib/asyncio/unix_events.py 81.48% <0.00%> (-0.24%) ⬇️
Lib/ast.py 74.08% <0.00%> (-0.15%) ⬇️
Lib/test/test_io.py 94.86% <0.00%> (-0.04%) ⬇️
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 66b7973...a9b9e8a. Read the comment docs.

if (init) {
_PyThreadState_Init(tstate);
}

HEAD_LOCK(runtime);
tstate->id = ++interp->tstate_next_unique_id;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, is the reason for the problem that the increment was done unlocked?

@skrah
Copy link
Contributor Author

skrah commented Mar 2, 2020

@vstinner Yes, it deserves a blurb. :)

@pitrou Yes, I printed tstate->id in the reproducer code and it had tons of duplicates. So

var->var_cached_tsid == ts->id &&

sometimes returned cached values that had already been deallocated by a previous thread
with a duplicate id.

With this fix there are no longer any duplicates and the test does not crash. If you review,
could you glance at https://bugs.python.org/file48930/threaded_crash.zip and verify that
it is actually correct embedding code (I think it is). :)

ASAN in release mode still complains about another invalid read in ceval.c, but I
think that is unrelated (it is also present in master).

@pitrou
Copy link
Member

pitrou commented Mar 2, 2020

Yes, threaded_crash.zip seems to be ok.

if (init) {
_PyThreadState_Init(tstate);
}

HEAD_LOCK(runtime);
tstate->id = ++interp->tstate_next_unique_id;
Copy link
Contributor Author

@skrah skrah Mar 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The location is unfortunate, but _PyThreadState_Init(tstate) does not use this field.

Copy link
Member

@pitrou pitrou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 from me.

@bedevere-bot
Copy link

@skrah: Please replace # with GH- in the commit message next time. Thanks!

@miss-islington
Copy link
Contributor

Thanks @skrah for the PR 🌮🎉.. I'm working now to backport this PR to: 3.7, 3.8.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington
Copy link
Contributor

Sorry @skrah, I had trouble checking out the 3.8 backport branch.
Please backport using cherry_picker on command line.
cherry_picker b3b9ade4a3d3fe00d933bcd8fc5c5c755d1024f9 3.8

@miss-islington
Copy link
Contributor

Sorry, @skrah, I could not cleanly backport this to 3.7 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker b3b9ade4a3d3fe00d933bcd8fc5c5c755d1024f9 3.7

@skrah
Copy link
Contributor Author

skrah commented Mar 2, 2020

Thanks! Backports will follow ...

@bedevere-bot
Copy link

GH-18752 is a backport of this pull request to the 3.8 branch.

@bedevere-bot
Copy link

GH-18753 is a backport of this pull request to the 3.7 branch.

skrah added a commit that referenced this pull request Mar 3, 2020
…#18752)

- Threads created by PyGILState_Ensure() could have a duplicate tstate->id.

(cherry picked from commit b3b9ade)
skrah added a commit that referenced this pull request Mar 3, 2020
- Threads created by PyGILState_Ensure() could have a duplicate tstate->id.

(cherry picked from commit b3b9ade)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants