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

PyThreadState_Next not thread safe #40857

Open
jpe mannequin opened this issue Sep 2, 2004 · 15 comments
Open

PyThreadState_Next not thread safe #40857

jpe mannequin opened this issue Sep 2, 2004 · 15 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-C-API

Comments

@jpe
Copy link
Mannequin

jpe mannequin commented Sep 2, 2004

BPO 1021318
Nosy @pitrou, @vstinner, @devdanzin, @jd, @ericsnowcurrently, @serhiy-storchaka

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:

assignee = None
closed_at = None
created_at = <Date 2004-09-02.16:56:47.000>
labels = ['interpreter-core', '3.9']
title = 'PyThreadState_Next not thread safe'
updated_at = <Date 2020-05-15.01:09:40.629>
user = 'https://bugs.python.org/jpe'

bugs.python.org fields:

activity = <Date 2020-05-15.01:09:40.629>
actor = 'vstinner'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2004-09-02.16:56:47.000>
creator = 'jpe'
dependencies = []
files = []
hgrepos = []
issue_num = 1021318
keywords = []
message_count = 14.0
messages = ['60562', '82072', '114376', '358187', '358188', '358189', '358190', '358191', '358192', '358261', '358262', '358347', '364094', '368895']
nosy_count = 7.0
nosy_names = ['jpe', 'pitrou', 'vstinner', 'ajaksu2', 'jd', 'eric.snow', 'serhiy.storchaka']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = None
url = 'https://bugs.python.org/issue1021318'
versions = ['Python 3.9']

@jpe
Copy link
Mannequin Author

jpe mannequin commented Sep 2, 2004

I can't convince myself that PyThreadState_Next is
thread safe even if the GIL is held because
PyGILState_Release can delete a thread state after
releasing the GIL if the gilstate_counter reaches 0.
So another thread could be deleting a thread state my
thread is referencing.

If the GIL was held when the thread state was deleted,
the I think the next function would be thread safe
because new thread states are always added to the front
of the list.

If these functions should work when the GIL is not
held, the head_mutex in pystate.c probably needs to be
exposed in some manner so code can lock it, iterate
through the threads, and then unlock it.

@jpe jpe mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Sep 2, 2004
@devdanzin
Copy link
Mannequin

devdanzin mannequin commented Feb 14, 2009

Can someone take a look a this and either close or propose what to do?

@BreamoreBoy
Copy link
Mannequin

BreamoreBoy mannequin commented Aug 19, 2010

No reply to msg82072.

@BreamoreBoy BreamoreBoy mannequin closed this as completed Aug 19, 2010
@BreamoreBoy BreamoreBoy mannequin closed this as completed Aug 19, 2010
@jd
Copy link
Mannequin

jd mannequin commented Dec 10, 2019

This is actually true and it's quite easy to produce a bug that triggers a segmentation fault when iterating over a large list of threads create dynamically.

That makes PyThreadState_Next barely usable for any program that has a few threads. The head mutex needs to be locked to be able to iterate safely over the list of thread.

@jd jd mannequin added 3.7 (EOL) end of life 3.8 (EOL) end of life 3.9 only security fixes labels Dec 10, 2019
@jd jd mannequin changed the title PyThreadState_Next not thread safe? PyThreadState_Next not thread safe Dec 10, 2019
@jd jd mannequin added 3.7 (EOL) end of life 3.8 (EOL) end of life 3.9 only security fixes labels Dec 10, 2019
@jd jd mannequin changed the title PyThreadState_Next not thread safe? PyThreadState_Next not thread safe Dec 10, 2019
@vstinner
Copy link
Member

This is actually true and it's quite easy to produce a bug that triggers a segmentation fault when iterating over a large list of threads create dynamically.

This issue is closed. Would you be able to write a reproducer script? If yes, maybe open a new issue, or I can reopen this one.

@jd
Copy link
Mannequin

jd mannequin commented Dec 10, 2019

It'd be great if you could reopen it. I'm interested in fixing it properly.

It's impossible to "solve" in Python 2 since the head mutex is not accessible (it's static in pystate.c) but this is doable with Python 3 (yay).

We'd simply need to provide a new API to lock/unlock the interpreter's mutex.

How hard to you need the script to reproduce? I can try to spend some time to extract some of my code to have one if that's really needed (I'm using Cython to generate some of the C code).

@vstinner
Copy link
Member

I reopened the issue and changed the version to 3.9.

@vstinner vstinner removed 3.7 (EOL) end of life 3.8 (EOL) end of life labels Dec 10, 2019
@vstinner vstinner reopened this Dec 10, 2019
@vstinner vstinner removed 3.7 (EOL) end of life 3.8 (EOL) end of life labels Dec 10, 2019
@vstinner vstinner reopened this Dec 10, 2019
@vstinner
Copy link
Member

We'd simply need to provide a new API to lock/unlock the interpreter's mutex.

Are you talking about this lock?

#define HEAD_LOCK(runtime) \
    PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK)
#define HEAD_UNLOCK(runtime) \
    PyThread_release_lock((runtime)->interpreters.mutex)

@jd
Copy link
Mannequin

jd mannequin commented Dec 10, 2019

Yes, that's the one 👍

@jd
Copy link
Mannequin

jd mannequin commented Dec 11, 2019

Victor, do you have an idea of how you would like this mutex to be exposed?

I see it only recently changed in Python 3.7 to be part of a structure, though this structure is not public AFAIU.

Is adding 2 new lock/unlock C functions good enough?

@vstinner
Copy link
Member

I'm not sure of what is the best approach. Currently, bpo-10915 is blocking different projects: "Make the PyGILState API compatible with multiple interpreters". We may have to fix this API first, and clarify the scope of the different locks.

@ericsnowcurrently
Copy link
Member

On Wed, Dec 11, 2019 at 7:02 AM STINNER Victor <report@bugs.python.org> wrote:

We may have to fix this API first, and clarify the scope of the different locks.

+1

@vstinner
Copy link
Member

See also bpo-35370: "Add _PyEval_SetTrace(tstate, func, arg) function".

@vstinner
Copy link
Member

I marked bpo-26461 as a duplicate of this issue.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 9, 2022
@iritkatriel iritkatriel added 3.12 bugs and security fixes and removed 3.9 only security fixes labels Jun 15, 2022
@erlend-aasland erlend-aasland removed the 3.12 bugs and security fixes label May 14, 2024
@a7a-dar

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-C-API
Projects
Status: No status
Development

No branches or pull requests

5 participants