Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Nov 19, 2023
1 parent 3417b26 commit 922a166
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 28 deletions.
54 changes: 29 additions & 25 deletions _pydevd_sys_monitoring/pydevd_sys_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,13 +418,13 @@ def get_func_code_info(code_obj, frame_or_depth) -> FuncCodeInfo:


def _enable_line_tracing(code):
print('enable line tracing', code)
# print('enable line tracing', code)
events = monitor.get_local_events(DEBUGGER_ID, code)
monitor.set_local_events(DEBUGGER_ID, code, events | monitor.events.LINE)


def _enable_return_tracing(code):
print('enable return tracing', code)
# print('enable return tracing', code)
events = monitor.get_local_events(DEBUGGER_ID, code)
monitor.set_local_events(DEBUGGER_ID, code, events | monitor.events.PY_RETURN)

Expand All @@ -434,25 +434,25 @@ def disable_code_tracing(code):


def enable_code_tracing(thread, code, frame):
DEBUG = False # 'my_code.py' in code.co_filename or 'other.py' in code.co_filename
if DEBUG:
print('==== enable code tracing', code.co_filename[-30:], code.co_name)
# DEBUG = False # 'my_code.py' in code.co_filename or 'other.py' in code.co_filename
# if DEBUG:
# print('==== enable code tracing', code.co_filename[-30:], code.co_name)
return _enable_code_tracing(thread, code, frame, False)


def _enable_code_tracing(thread, code, frame, warn_on_filtered_out):
DEBUG = False # 'my_code.py' in code.co_filename or 'other.py' in code.co_filename
# DEBUG = False # 'my_code.py' in code.co_filename or 'other.py' in code.co_filename

py_db: object = GlobalDebuggerHolder.global_dbg
if py_db is None or py_db.pydb_disposed:
if DEBUG:
print('disable (no py_db)')
# if DEBUG:
# print('disable (no py_db)')
return monitor.DISABLE

func_code_info: FuncCodeInfo = get_func_code_info(code, frame)
if func_code_info.always_skip_code:
if DEBUG:
print('disable (always skip)')
# if DEBUG:
# print('disable (always skip)')
return monitor.DISABLE

try:
Expand All @@ -466,8 +466,8 @@ def _enable_code_tracing(thread, code, frame, warn_on_filtered_out):
is_stepping = step_cmd != -1

if func_code_info.always_filtered_out:
if DEBUG:
print('disable (always filtered out)')
# if DEBUG:
# print('disable (always filtered out)')
if warn_on_filtered_out and is_stepping and info.pydev_original_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE) and not _global_notify_skipped_step_in:
_notify_skipped_step_in_because_of_filters(py_db, frame)

Expand Down Expand Up @@ -538,7 +538,7 @@ def _unwind_event(code, instruction, exc):
if func_code_info.always_skip_code:
return

print('_unwind_event', code, exc)
# print('_unwind_event', code, exc)
frame = sys._getframe(1)
arg = (type(exc), exc, exc.__traceback__)

Expand All @@ -558,7 +558,7 @@ def _unwind_event(code, instruction, exc):
func_code_info.try_except_container_obj = container_obj

if is_unhandled_exception(func_code_info.try_except_container_obj, py_db, frame, user_uncaught_exc_info[1], user_uncaught_exc_info[2]):
print('stop in user uncaught')
# print('stop in user uncaught')
handle_exception(py_db, thread_info.thread, frame, user_uncaught_exc_info[0], EXCEPTION_TYPE_USER_UNHANDLED)
return

Expand Down Expand Up @@ -600,12 +600,12 @@ def _raise_event(code, instruction, exc):
if func_code_info.always_skip_code:
return

print('_raise_event --- ', code, exc)
# print('_raise_event --- ', code, exc)

frame = sys._getframe(1)
arg = (type(exc), exc, exc.__traceback__)
should_stop, frame, _user_uncaught_exc_info = should_stop_on_exception(py_db, thread_info.additional_info, frame, thread_info.thread, arg, None)
print('!!!! should_stop (in raise)', should_stop)
# print('!!!! should_stop (in raise)', should_stop)
if should_stop:
handle_exception(py_db, thread_info.thread, frame, arg, EXCEPTION_TYPE_HANDLED)
return
Expand Down Expand Up @@ -915,7 +915,7 @@ def _line_event(code, line):
stop_reason,
suspend_other_threads=bp and bp.suspend_policy == "ALL",
)
print('suspend on breakpoint...')
# print('suspend on breakpoint...')
py_db.do_wait_suspend(thread_info.thread, frame, 'line', None)
return
# elif stop_on_plugin_breakpoint and plugin_manager is not None:
Expand All @@ -925,7 +925,7 @@ def _line_event(code, line):

if info.pydev_state == STATE_SUSPEND:
# Note: it's possible that it was suspended with a pause (and we'd stop here too).
print('suspend (pause)...')
# print('suspend (pause)...')
py_db.do_wait_suspend(thread_info.thread, frame, 'line', None)
return

Expand Down Expand Up @@ -1042,7 +1042,7 @@ def _start_method(code, instruction_offset):

def start_monitoring(all_threads=False):
if all_threads:
print('start monitoring, all_threads=', all_threads)
# print('start monitoring, all_threads=', all_threads)
DEBUGGER_ID = monitor.DEBUGGER_ID
if not monitor.get_tool(DEBUGGER_ID):
monitor.use_tool_id(DEBUGGER_ID, 'pydevd')
Expand All @@ -1055,15 +1055,15 @@ def start_monitoring(all_threads=False):
# code=None means we can already get the threading.current_thread.
thread_info = _get_thread_info(True, 1)
if thread_info is None:
print('start monitoring, thread=', None)
# print('start monitoring, thread=', None)
return
print('start monitoring, thread=', thread_info.thread)
# print('start monitoring, thread=', thread_info.thread)
thread_info.trace = True


def stop_monitoring(all_threads=False):
if all_threads:
print('stop monitoring, all_threads=', all_threads)
# print('stop monitoring, all_threads=', all_threads)
if monitor.get_tool(monitor.DEBUGGER_ID) == 'pydevd':
monitor.set_events(monitor.DEBUGGER_ID, 0)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, None)
Expand All @@ -1079,7 +1079,7 @@ def stop_monitoring(all_threads=False):
thread_info = _get_thread_info(False, 1)
if thread_info is None:
return
print('stop monitoring, thread=', thread_info.thread)
# print('stop monitoring, thread=', thread_info.thread)
thread_info.trace = False


Expand All @@ -1089,6 +1089,10 @@ def update_monitor_events(suspend_requested: Optional[bool]=None) -> None:
:param suspend: means the user requested threads to be suspended
'''
if monitor.get_tool(monitor.DEBUGGER_ID) != 'pydevd':
# It is still not initialized.
return

# 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 @@ -1120,7 +1124,7 @@ def update_monitor_events(suspend_requested: Optional[bool]=None) -> None:

if has_caught_exception_breakpoint_in_pydb:
required_events |= monitor.events.RAISE | monitor.events.PY_UNWIND
print('track RAISE')
# print('track RAISE')
monitor.register_callback(DEBUGGER_ID, monitor.events.RAISE, _raise_event)
monitor.register_callback(DEBUGGER_ID, monitor.events.PY_UNWIND, _unwind_event)
else:
Expand All @@ -1141,7 +1145,7 @@ def update_monitor_events(suspend_requested: Optional[bool]=None) -> None:
break

if has_line_breaks or suspend_requested:
print('track PY_START|PY_RESUME, suspend_requested=', 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)
Expand Down
10 changes: 8 additions & 2 deletions pydevd.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,8 @@ def __init__(self, set_as_global=True):

self.variable_presentation = PyDevdAPI.VariablePresentation()

# mtime to be raised when breakpoints change
# mtime to be raised when something that will affect the
# tracing in place (such as breakpoints change or filtering).
self.mtime = 0

self.file_to_id_to_line_breakpoint = {}
Expand Down Expand Up @@ -1262,14 +1263,19 @@ def _clear_filters_caches(self):
self._is_libraries_filter_enabled = self._files_filtering.use_libraries_filter()
self.is_files_filter_enabled = self._exclude_filters_enabled or self._is_libraries_filter_enabled

self.mtime += 1
if USE_SYS_MONITORING:
pydevd_sys_monitoring.update_monitor_events()
pydevd_sys_monitoring.restart_events()

def clear_dont_trace_start_end_patterns_caches(self):
# When start/end patterns are changed we must clear all caches which would be
# affected by a change in get_file_type() and reset the tracing function
# as places which were traced may no longer need to be traced and vice-versa.
self.on_breakpoints_changed()
_CACHE_FILE_TYPE.clear()
self._clear_filters_caches()
self._clear_skip_caches()
self._clear_filters_caches()

def _exclude_by_filter(self, frame, absolute_filename):
'''
Expand Down
5 changes: 4 additions & 1 deletion tests_python/test_debugger_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from _pydevd_bundle.pydevd_constants import (int_types, IS_64BIT_PROCESS,
PY_VERSION_STR, PY_IMPL_VERSION_STR, PY_IMPL_NAME, IS_PY36_OR_GREATER,
IS_PYPY, GENERATED_LEN_ATTR_NAME, IS_WINDOWS, IS_LINUX, IS_MAC, IS_PY38_OR_GREATER,
IS_PY311_OR_GREATER)
IS_PY311_OR_GREATER, USE_SYS_MONITORING)
from tests_python import debugger_unittest
from tests_python.debug_constants import TEST_CHERRYPY, TEST_DJANGO, TEST_FLASK, \
IS_CPYTHON, TEST_GEVENT, TEST_CYTHON, TODO_PY311
Expand Down Expand Up @@ -6596,6 +6596,9 @@ def run(self):
@pytest.mark.parametrize('soft_kill', [False, True])
def test_soft_terminate(case_setup_dap, pyfile, soft_kill):

if soft_kill and USE_SYS_MONITORING:
pytest.skip('Right now when using sys.monitoring exceptions are be handled in callbacks.')

@pyfile
def target():
import time
Expand Down

0 comments on commit 922a166

Please sign in to comment.