Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

debugpy 1.8.19 creates _DummyThread when inspecting PySide6 QThread under Python 3.13, causing teardown crash

未关闭
#1,985 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
python
领域
devtools

调研方向

从 debugpy/_pydevd_sys_monitoring.py 中的 _create_thread_info() 开始,然后使用列出的 Python 3.13.4、PySide6、requests 和 debugpy 版本运行 qt_debugpy_repro.py。跟踪 QThread 如何到达 threading.current_thread(),并验证该复现不再留下不需要的 _DummyThread,也不再报告关闭时的崩溃。

由索引模型根据 Issue 内容生成。

描述

bug

Summary

When debugging a PySide6 application using debugpy 1.8.19 (via VS Code Python Debugger extension 2025.18.0) on Python 3.13.4, debugpy’s sys‑monitoring creates _DummyThread objects while inspecting a QThread that performs HTTP requests (requests/urllib3).
During interpreter shutdown, Python 3.13 attempts to finalize these _DummyThread objects and crashes with:

Exception ignored in: <function _DeleteDummyThreadOnDel.__del__>
TypeError: 'NoneType' object does not support the context manager protocol

This does not occur:

  • when running the same code outside VS Code (no debugpy)
  • when using only Python threads
  • when using QThread without debugpy
  • when using requests/urllib3 without debugpy

The issue is reproducible with a minimal PySide6 + requests script.

I have not tested this on Python 3.12, so I cannot confirm whether the issue is specific to Python 3.13 or also affects earlier versions


Environment

  • Python: 3.13.4 (Windows x64)
  • VS Code Python Debugger extension: 2025.18.0
  • debugpy version: 1.8.19
    (verified via import debugpy; debugpy.__version__)
  • OS: Windows 11
  • PySide6: 6.10.1
  • requests: 2.32.5
  • urllib3: 2.6.0

Minimal pip freeze:

certifi==2025.11.12
charset-normalizer==3.4.4
idna==3.11
PySide6==6.10.1
PySide6_Addons==6.10.1
PySide6_Essentials==6.10.1
requests==2.32.5
shiboken6==6.10.1
urllib3==2.6.0

Minimal Reproduction

qt_debugpy_repro.py:

import sys
import time
import threading
import requests
from PySide6.QtCore import QObject, QThread, Signal
from PySide6.QtWidgets import QApplication

import debugpy
print(f"debugpy version: {debugpy.__version__}")

class Worker(QObject):
    tick = Signal()

    def run(self):
        # Simulate Spotipy/urllib3 behavior: property access on HTTPResponse
        for _ in range(3):
            r = requests.get("https://httpbin.org/get")
            _ = r.raw.closed  # <-- triggers urllib3.response.closed
            time.sleep(0.1)
        print("worker done")


def dump_threads(label):
    print(f"\nTHREADS {label}:")
    for t in threading.enumerate():
        print(" -", t, "daemon=", t.daemon, "type=", type(t))


def main():
    app = QApplication(sys.argv)

    worker = Worker()
    thread = QThread()
    worker.moveToThread(thread)
    thread.started.connect(worker.run)

    thread.start()

    QThread.msleep(500)

    dump_threads("BEFORE SHUTDOWN")

    # Stop QThread without joining (mirrors real-world teardown timing)
    thread.quit()

    dump_threads("AFTER QUIT")

    print("exiting app")
    sys.exit(0)


if __name__ == "__main__":
    main()

Steps to Reproduce

  1. Open the script in VS Code
  2. Select Python 3.13.4 interpreter
  3. Use this launch.json:
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Debug Repro",
            "type": "python",
            "request": "launch",
            "program": "${workspaceFolder}/qt_debugpy_repro.py",
            "console": "integratedTerminal",
            "python": "${workspaceFolder}/venv/Scripts/python"
        }
    ]
}
  1. Run with Start Debugging
  2. Observe thread list and shutdown behavior

Observed Behavior (under debugpy)

In the minimal reproduction code listed above, debugpy creates a _DummyThread when inspecting a PySide6 QThread.
The minimal repro does not crash Python, but it clearly shows the unexpected _DummyThread created by debugpy:

THREADS BEFORE SHUTDOWN:
 - <_MainThread(MainThread, ...)>
 - <_DummyThread(Dummy-6, ...)>

THREADS AFTER QUIT:
 - <_MainThread(MainThread, ...)>
 - <_DummyThread(Dummy-6, ...)>

exiting app
QThread: Destroyed while thread '' is still running

Behavior in the full application

In my real application (which uses the same pattern but performs more work inside the QThread), the _DummyThread created by debugpy survives until interpreter shutdown.
On Python 3.13.4 this leads to a teardown crash:

Exception ignored in: <function _DeleteDummyThreadOnDel.__del__>
TypeError: 'NoneType' object has no support for the context manager protocol

This crash does not occur outside debugpy.

The _DummyThread is created by debugpy’s sys‑monitoring:

Example captured stack:

=== DummyThread created ===
  File "qt_debugpy_repro.py", line XX, in run
  File "...debugpy/_pydevd_sys_monitoring.py", line 330, in _create_thread_info
    t = threading.current_thread()
  File "threading.py", line 1439, in current_thread
    return _DummyThread()
=== end DummyThread stack ===

Expected Behavior

  • No _DummyThread should be created for QThreads
  • No crash during interpreter shutdown
  • Behavior should match Python 3.12 and non-debugpy execution

Analysis

  • QThread is not a Python threading.Thread
  • debugpy’s sys‑monitoring inspects thread state during property access (urllib3.response.closed)
  • threading.current_thread() returns _DummyThread() when the thread is not in threading._active
  • Python 3.13 changed teardown order
  • _DummyThread.__del__ now runs after parts of threading are already destroyed
  • This leads to the observed TypeError during shutdown

This issue does not occur with:

  • Python threads
  • QThreads without debugpy
  • requests/urllib3 without debugpy

Only the combination of debugpy + QThread + urllib3 + Python 3.13 triggers it.


Possible Fix Direction

  • Avoid calling threading.current_thread() on non‑Python threads
  • Or guard _create_thread_info() against QThreads
  • Or avoid creating _DummyThread objects during sys‑monitoring
  • Or ensure _DummyThread is not left alive until interpreter teardown

Thank you

Happy to test patches or provide additional instrumentation if needed.

主要语言
Python
星标
2.5k
派生
202
平均合并
5 天 1 小时
30 天内合并 PR
1

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

microsoft/debugpy 的其他 Issue

查看 microsoft/debugpy 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。