Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Nov 15, 2023
1 parent 1004440 commit 3349521
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 15 deletions.
3 changes: 3 additions & 0 deletions _pydevd_bundle/pydevd_thread_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ def suspend_all_threads(py_db, except_thread):
Suspend all except the one passed as a parameter.
:param except_thread:
'''
if USE_SYS_MONITORING:
pydevd_sys_monitoring.update_monitor_events(suspend_requested=True)

pydev_log.info('Suspending all threads except: %s', except_thread)
all_threads = pydevd_utils.get_non_pydevd_threads()
for t in all_threads:
Expand Down
36 changes: 24 additions & 12 deletions _pydevd_sys_monitoring/pydevd_sys_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
import threading
from types import CodeType, FrameType
from typing import Dict, Optional, Set, Tuple
from typing import Dict, Optional, Set, Tuple, Literal
from os.path import basename, splitext

from _pydev_bundle import pydev_log
Expand Down Expand Up @@ -902,7 +902,8 @@ def start_monitoring(all_threads=False):
DEBUGGER_ID = monitor.DEBUGGER_ID
if not monitor.get_tool(DEBUGGER_ID):
monitor.use_tool_id(DEBUGGER_ID, 'pydevd')
restart_events(breakpoints_changed=True)
update_monitor_events()
restart_events()
else:
try:
thread_info = _thread_local_info.thread_info
Expand Down Expand Up @@ -938,10 +939,13 @@ def stop_monitoring(all_threads=False):
thread_info.trace = False


def restart_events(breakpoints_changed: bool=False) -> None:
print('restart events, breakpoints_changed=', breakpoints_changed)
sys.monitoring.restart_events()
if breakpoints_changed:
def update_monitor_events(suspend_requested: bool=False) -> None:
'''
This should be called when breakpoints change.
:param suspend: means the user requested threads to be suspended
'''
if suspend_requested:
# When breakpoints change we need to update what we want to track based
# on the breakpoints.
py_db = GlobalDebuggerHolder.global_dbg
Expand Down Expand Up @@ -979,23 +983,31 @@ def restart_events(breakpoints_changed: bool=False) -> None:
has_line_breaks = True
break

if has_line_breaks:
print('track PY_START|PY_RESUME')
if has_line_breaks or suspend_requested:
print('track PY_START|PY_RESUME, suspend_requested=', suspend_requested)
required_events |= monitor.events.PY_START | monitor.events.PY_RESUME

monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, _start_method)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, _start_method)
monitor.register_callback(DEBUGGER_ID, monitor.events.LINE, _line_event)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RETURN, _return_event)

else:
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, _start_method)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, _start_method)
monitor.register_callback(DEBUGGER_ID, monitor.events.LINE, _line_event)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RETURN, _return_event)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, None)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, None)
monitor.register_callback(DEBUGGER_ID, monitor.events.LINE, None)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RETURN, None)

monitor.set_events(DEBUGGER_ID, required_events)


def restart_events() -> None:
# Note: if breakpoints change, update_monitor_events usually needs to be
# called first, then the line event tracing must be set for existing frames
# and then this function must be called at the end.
sys.monitoring.restart_events()


def _is_same_frame(info, target_frame, current_frame):
if target_frame is current_frame:
return True
Expand Down
10 changes: 7 additions & 3 deletions pydevd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,8 @@ def on_breakpoints_changed(self, removed=False):
def set_tracing_for_untraced_contexts(self, breakpoints_changed=False):
# Enable the tracing for existing threads (because there may be frames being executed that
# are currently untraced).
if USE_SYS_MONITORING and breakpoints_changed:
pydevd_sys_monitoring.update_monitor_events()

if IS_CPYTHON:
# Note: use sys._current_frames instead of threading.enumerate() because this way
Expand Down Expand Up @@ -1213,7 +1215,7 @@ def set_tracing_for_untraced_contexts(self, breakpoints_changed=False):
additional_info = None

if USE_SYS_MONITORING:
pydevd_sys_monitoring.restart_events(breakpoints_changed=breakpoints_changed)
pydevd_sys_monitoring.restart_events()

@property
def multi_threads_single_notification(self):
Expand Down Expand Up @@ -1920,6 +1922,9 @@ def set_suspend(self, thread, stop_reason, suspend_other_threads=False, is_pause
info = mark_thread_suspended(thread, stop_reason, original_step_cmd=original_step_cmd)

if is_pause:
if USE_SYS_MONITORING:
pydevd_sys_monitoring.update_monitor_events(suspend_requested=True)

# Must set tracing after setting the state to suspend.
frame = info.get_topmost_frame(thread)
if frame is not None:
Expand All @@ -1943,8 +1948,7 @@ def set_suspend(self, thread, stop_reason, suspend_other_threads=False, is_pause
# Suspend all except the current one (which we're currently suspending already).
suspend_all_threads(self, except_thread=thread)

if is_pause and not suspend_other_threads and USE_SYS_MONITORING:
# When suspending other threads this is already called.
if USE_SYS_MONITORING:
pydevd_sys_monitoring.restart_events()

def _send_breakpoint_condition_exception(self, thread, conditional_breakpoint_exception_tuple):
Expand Down

0 comments on commit 3349521

Please sign in to comment.