Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

os.fork() called from DummyThread confuses threading shutdown logic #102512

Closed
Labels
3.11only security fixes3.12only security fixes3.13bugs and security fixestopic-multiprocessingtype-bugAn unexpected behavior, bug, or error
@marmarek

Description

@marmarek

Bug report

threading._shutdown() relies on_main_thread having_tstate_lock notNone (there is assert for that). When fork is called from a DummyThread (in my case, that's a thread created by (Py)Qt), it gets promoted to main thread, but remains very simplistic DummyThread. Especially, nobody initializes its_tstate_lock.threading._after_fork() handles the case of current thread not being in_active dict at all (by creating new MainThread object), but it doesn't handle the case of having DummyThread there already. This results in AssertionError in thread shutdown method - which for example confusesmultiprocessing.Process (it gets exit code 1, even if the process function was successful).

Reproducer:

#!/usr/bin/python3import threadingimport multiprocessingimport _threadclass Bar(multiprocessing.Process):    def run(self):        print("process")def run_thread(lock):    # the call to current_thread() is crucial for reproducer - it allocates    # DummyThread()    print(f"thread: {threading.current_thread()}")    p = Bar()    p.start()    p.join()    print(f"proc exit code: {p.exitcode}")    lock.release()def main():    lock = _thread.allocate_lock()    lock.acquire()    t = _thread.start_new_thread(run_thread, (lock,))    # t.join    lock.acquire()    print(f"thread exit")main()

It should print:

thread: <_DummyThread(Dummy-1, started daemon 135243893053120)>processproc exit code: 0thread exit

but it prints:

thread: <_DummyThread(Dummy-1, started daemon 135243893053120)>processproc exit code: 1thread exit

(see exit code difference)

multiprocessing.Process (or rathermultiprocessing.popen_fork.Popen._launch() to be specific) swallows the exception, but adding some debug prints there I get:

Traceback (most recent call last):  File "/usr/lib64/python3.11/multiprocessing/popen_fork.py", line 71, in _launch    code = process_obj._bootstrap(parent_sentinel=child_r)           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  File "/usr/lib64/python3.11/multiprocessing/process.py", line 332, in _bootstrap    threading._shutdown()  File "/usr/lib64/python3.11/threading.py", line 1553, in _shutdown    assert tlock is not None           ^^^^^^^^^^^^^^^^^

Your environment

  • CPython versions tested on: 3.11.2
  • Operating system and architecture: Fedora 37, x86_64

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixes3.12only security fixes3.13bugs and security fixestopic-multiprocessingtype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp