mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Fix debugger stepping actions in forked process (#1921)
* Fix debugger stepping actions in forked process Fix the debugger stepping state when debugging a process that has been forked from the main process. The new sys.monitoring mechanism didn't fully clear the thread local storage after a fork leading to a state where the forked child process tracked the wrong thread information and was never updated on the latest continue action. * Add stepping test for forked process * Add line ending back in for cleaner diff * More formatting reversions
This commit is contained in:
parent
b387710b7f
commit
ea1dd9a838
6 changed files with 2424 additions and 2231 deletions
|
|
@ -115,7 +115,7 @@ In order to update the source, you would:
|
|||
You might need to regenerate the Cython modules after any changes. This can be done by:
|
||||
|
||||
- Install Python latest (3.12 as of this writing)
|
||||
- pip install cython, django>=1.9, setuptools>=0.9, wheel>0.21, twine
|
||||
- pip install cython 'django>=1.9' 'setuptools>=0.9' 'wheel>0.21' twine
|
||||
- On a windows machine:
|
||||
- set FORCE_PYDEVD_VC_VARS=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat
|
||||
- in the pydevd folder: python .\build_tools\build.py
|
||||
|
|
|
|||
|
|
@ -755,6 +755,16 @@ def enable_code_tracing(thread_ident: Optional[int], code, frame) -> bool:
|
|||
|
||||
return _enable_code_tracing(py_db, additional_info, func_code_info, code, frame, False)
|
||||
|
||||
# fmt: off
|
||||
# IFDEF CYTHON
|
||||
# cpdef reset_thread_local_info():
|
||||
# ELSE
|
||||
def reset_thread_local_info():
|
||||
# ENDIF
|
||||
# fmt: on
|
||||
"""Resets the thread local info TLS store for use after a fork()."""
|
||||
global _thread_local_info
|
||||
_thread_local_info = threading.local()
|
||||
|
||||
# fmt: off
|
||||
# IFDEF CYTHON
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -761,6 +761,16 @@ cpdef enable_code_tracing(unsigned long thread_ident, code, frame):
|
|||
|
||||
return _enable_code_tracing(py_db, additional_info, func_code_info, code, frame, False)
|
||||
|
||||
# fmt: off
|
||||
# IFDEF CYTHON -- DONT EDIT THIS FILE (it is automatically generated)
|
||||
cpdef reset_thread_local_info():
|
||||
# ELSE
|
||||
# def reset_thread_local_info():
|
||||
# ENDIF
|
||||
# fmt: on
|
||||
"""Resets the thread local info TLS store for use after a fork()."""
|
||||
global _thread_local_info
|
||||
_thread_local_info = threading.local()
|
||||
|
||||
# fmt: off
|
||||
# IFDEF CYTHON -- DONT EDIT THIS FILE (it is automatically generated)
|
||||
|
|
|
|||
|
|
@ -3354,6 +3354,9 @@ def settrace_forked(setup_tracing=True):
|
|||
if clear_thread_local_info is not None:
|
||||
clear_thread_local_info()
|
||||
|
||||
if PYDEVD_USE_SYS_MONITORING:
|
||||
pydevd_sys_monitoring.reset_thread_local_info()
|
||||
|
||||
settrace(
|
||||
host,
|
||||
port=port,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ def test_multiprocessing(pyfile, target, run, start_method):
|
|||
p.join()
|
||||
|
||||
def child(q, a):
|
||||
print("entering child")
|
||||
print("entering child") # @bp
|
||||
assert q.get() == "foo?"
|
||||
a.put(Foo())
|
||||
|
||||
|
|
@ -136,7 +136,20 @@ def test_multiprocessing(pyfile, target, run, start_method):
|
|||
|
||||
with debug.Session(child_config) as child_session:
|
||||
with child_session.start():
|
||||
pass
|
||||
child_session.set_breakpoints(code_to_debug, all)
|
||||
|
||||
expected_frame = some.dap.frame(code_to_debug, line="bp")
|
||||
stop = child_session.wait_for_stop(
|
||||
"breakpoint",
|
||||
expected_frames=[expected_frame],
|
||||
)
|
||||
child_session.request('stepIn', {"threadId": stop.thread_id})
|
||||
|
||||
stop = child_session.wait_for_stop(
|
||||
"step",
|
||||
expected_frames=[some.dap.frame(code_to_debug, line=expected_frame.items['line'] + 1)],
|
||||
)
|
||||
child_session.request_continue()
|
||||
|
||||
expected_grandchild_config = expected_subprocess_config(child_session)
|
||||
grandchild_config = child_session.wait_for_next_event("debugpyAttach")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue