mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fixes after review (PY-24026)
Enable frame evaluation debugging back after stepping and disable it if exception breakpoints were added. It also contains some renames and extracting of code for breakpoints handling.
This commit is contained in:
@@ -51,7 +51,7 @@ class LineBreakpoint(object):
|
||||
self.expression = expression
|
||||
self.suspend_policy = suspend_policy
|
||||
# need for frame evaluation: list of code objects, which bytecode was modified by this breakpoint
|
||||
self.code_objects = []
|
||||
self.code_objects = set()
|
||||
|
||||
def get_exception_full_qname(exctype):
|
||||
if not exctype:
|
||||
|
||||
@@ -1443,32 +1443,3 @@ def pydevd_find_thread_by_id(thread_id):
|
||||
traceback.print_exc()
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def enable_tracing_in_frames(main_debugger):
|
||||
""" If frame evaluation is enabled and breakpoint was added while running debug session there are two cases:
|
||||
* the frame isn't under execution yet, we'll handle all its breakpoints in frame evaluation function
|
||||
* the frame is already under execution, we need to enable old tracing function and disable it after exiting the frame
|
||||
"""
|
||||
if not main_debugger.ready_to_run:
|
||||
# do it it only debug session is started
|
||||
return
|
||||
|
||||
threads = threading.enumerate()
|
||||
try:
|
||||
for t in threads:
|
||||
if getattr(t, 'is_pydev_daemon_thread', False):
|
||||
continue
|
||||
additional_info = None
|
||||
try:
|
||||
additional_info = t.additional_info
|
||||
except AttributeError:
|
||||
pass # that's ok, no info currently set
|
||||
if additional_info is None:
|
||||
continue
|
||||
|
||||
for frame in additional_info.iter_frames(t):
|
||||
main_debugger.set_trace_for_frame_and_parents(frame, overwrite_prev_trace=True)
|
||||
main_debugger.set_use_code_extra(False)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -164,6 +164,51 @@ TRACE_PROPERTY = 'pydevd_traceproperty.py'
|
||||
get_file_type = DONT_TRACE.get
|
||||
|
||||
|
||||
def handle_breakpoint_condition(py_db, info, breakpoint, new_frame):
|
||||
condition = breakpoint.condition
|
||||
try:
|
||||
return eval(condition, new_frame.f_globals, new_frame.f_locals)
|
||||
|
||||
except:
|
||||
if type(condition) != type(''):
|
||||
if hasattr(condition, 'encode'):
|
||||
condition = condition.encode('utf-8')
|
||||
|
||||
msg = 'Error while evaluating expression: %s\n' % (condition,)
|
||||
sys.stderr.write(msg)
|
||||
traceback.print_exc()
|
||||
if not py_db.suspend_on_breakpoint_exception:
|
||||
return False
|
||||
else:
|
||||
stop = True
|
||||
try:
|
||||
# add exception_type and stacktrace into thread additional info
|
||||
etype, value, tb = sys.exc_info()
|
||||
try:
|
||||
error = ''.join(traceback.format_exception_only(etype, value))
|
||||
stack = traceback.extract_stack(f=tb.tb_frame.f_back)
|
||||
|
||||
# On self.set_suspend(thread, CMD_SET_BREAK) this info will be
|
||||
# sent to the client.
|
||||
info.conditional_breakpoint_exception = \
|
||||
('Condition:\n' + condition + '\n\nError:\n' + error, stack)
|
||||
finally:
|
||||
etype, value, tb = None, None, None
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
def handle_breakpoint_expression(breakpoint, info, new_frame):
|
||||
try:
|
||||
try:
|
||||
val = eval(breakpoint.expression, new_frame.f_globals, new_frame.f_locals)
|
||||
except:
|
||||
val = sys.exc_info()[1]
|
||||
finally:
|
||||
if val is not None:
|
||||
info.pydev_message = str(val)
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# PyDBFrame
|
||||
#=======================================================================================================================
|
||||
@@ -644,48 +689,12 @@ cdef class PyDBFrame:
|
||||
if stop or exist_result:
|
||||
condition = breakpoint.condition
|
||||
if condition is not None:
|
||||
try:
|
||||
val = eval(condition, new_frame.f_globals, new_frame.f_locals)
|
||||
if not val:
|
||||
return self.trace_dispatch
|
||||
|
||||
except:
|
||||
if type(condition) != type(''):
|
||||
if hasattr(condition, 'encode'):
|
||||
condition = condition.encode('utf-8')
|
||||
|
||||
msg = 'Error while evaluating expression: %s\n' % (condition,)
|
||||
sys.stderr.write(msg)
|
||||
traceback.print_exc()
|
||||
if not main_debugger.suspend_on_breakpoint_exception:
|
||||
return self.trace_dispatch
|
||||
else:
|
||||
stop = True
|
||||
try:
|
||||
# add exception_type and stacktrace into thread additional info
|
||||
etype, value, tb = sys.exc_info()
|
||||
try:
|
||||
error = ''.join(traceback.format_exception_only(etype, value))
|
||||
stack = traceback.extract_stack(f=tb.tb_frame.f_back)
|
||||
|
||||
# On self.set_suspend(thread, CMD_SET_BREAK) this info will be
|
||||
# sent to the client.
|
||||
info.conditional_breakpoint_exception = \
|
||||
('Condition:\n' + condition + '\n\nError:\n' + error, stack)
|
||||
finally:
|
||||
etype, value, tb = None, None, None
|
||||
except:
|
||||
traceback.print_exc()
|
||||
eval_result = handle_breakpoint_condition(main_debugger, info, breakpoint, new_frame)
|
||||
if not eval_result:
|
||||
return self.trace_dispatch
|
||||
|
||||
if breakpoint.expression is not None:
|
||||
try:
|
||||
try:
|
||||
val = eval(breakpoint.expression, new_frame.f_globals, new_frame.f_locals)
|
||||
except:
|
||||
val = sys.exc_info()[1]
|
||||
finally:
|
||||
if val is not None:
|
||||
info.pydev_message = str(val)
|
||||
handle_breakpoint_expression(breakpoint, info, new_frame)
|
||||
|
||||
if not main_debugger.first_breakpoint_reached:
|
||||
if is_call:
|
||||
@@ -823,7 +832,7 @@ cdef class PyDBFrame:
|
||||
else:
|
||||
stop = False
|
||||
|
||||
if step_cmd != -1 and is_return and IS_PY3K and hasattr(frame, "f_back"):
|
||||
if stop and step_cmd != -1 and is_return and IS_PY3K and hasattr(frame, "f_back"):
|
||||
f_code = getattr(frame.f_back, 'f_code', None)
|
||||
if f_code is not None:
|
||||
back_filename = os.path.basename(f_code.co_filename)
|
||||
|
||||
@@ -37,6 +37,51 @@ TRACE_PROPERTY = 'pydevd_traceproperty.py'
|
||||
get_file_type = DONT_TRACE.get
|
||||
|
||||
|
||||
def handle_breakpoint_condition(py_db, info, breakpoint, new_frame):
|
||||
condition = breakpoint.condition
|
||||
try:
|
||||
return eval(condition, new_frame.f_globals, new_frame.f_locals)
|
||||
|
||||
except:
|
||||
if type(condition) != type(''):
|
||||
if hasattr(condition, 'encode'):
|
||||
condition = condition.encode('utf-8')
|
||||
|
||||
msg = 'Error while evaluating expression: %s\n' % (condition,)
|
||||
sys.stderr.write(msg)
|
||||
traceback.print_exc()
|
||||
if not py_db.suspend_on_breakpoint_exception:
|
||||
return False
|
||||
else:
|
||||
stop = True
|
||||
try:
|
||||
# add exception_type and stacktrace into thread additional info
|
||||
etype, value, tb = sys.exc_info()
|
||||
try:
|
||||
error = ''.join(traceback.format_exception_only(etype, value))
|
||||
stack = traceback.extract_stack(f=tb.tb_frame.f_back)
|
||||
|
||||
# On self.set_suspend(thread, CMD_SET_BREAK) this info will be
|
||||
# sent to the client.
|
||||
info.conditional_breakpoint_exception = \
|
||||
('Condition:\n' + condition + '\n\nError:\n' + error, stack)
|
||||
finally:
|
||||
etype, value, tb = None, None, None
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
def handle_breakpoint_expression(breakpoint, info, new_frame):
|
||||
try:
|
||||
try:
|
||||
val = eval(breakpoint.expression, new_frame.f_globals, new_frame.f_locals)
|
||||
except:
|
||||
val = sys.exc_info()[1]
|
||||
finally:
|
||||
if val is not None:
|
||||
info.pydev_message = str(val)
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# PyDBFrame
|
||||
#=======================================================================================================================
|
||||
@@ -517,48 +562,12 @@ class PyDBFrame:
|
||||
if stop or exist_result:
|
||||
condition = breakpoint.condition
|
||||
if condition is not None:
|
||||
try:
|
||||
val = eval(condition, new_frame.f_globals, new_frame.f_locals)
|
||||
if not val:
|
||||
return self.trace_dispatch
|
||||
|
||||
except:
|
||||
if type(condition) != type(''):
|
||||
if hasattr(condition, 'encode'):
|
||||
condition = condition.encode('utf-8')
|
||||
|
||||
msg = 'Error while evaluating expression: %s\n' % (condition,)
|
||||
sys.stderr.write(msg)
|
||||
traceback.print_exc()
|
||||
if not main_debugger.suspend_on_breakpoint_exception:
|
||||
return self.trace_dispatch
|
||||
else:
|
||||
stop = True
|
||||
try:
|
||||
# add exception_type and stacktrace into thread additional info
|
||||
etype, value, tb = sys.exc_info()
|
||||
try:
|
||||
error = ''.join(traceback.format_exception_only(etype, value))
|
||||
stack = traceback.extract_stack(f=tb.tb_frame.f_back)
|
||||
|
||||
# On self.set_suspend(thread, CMD_SET_BREAK) this info will be
|
||||
# sent to the client.
|
||||
info.conditional_breakpoint_exception = \
|
||||
('Condition:\n' + condition + '\n\nError:\n' + error, stack)
|
||||
finally:
|
||||
etype, value, tb = None, None, None
|
||||
except:
|
||||
traceback.print_exc()
|
||||
eval_result = handle_breakpoint_condition(main_debugger, info, breakpoint, new_frame)
|
||||
if not eval_result:
|
||||
return self.trace_dispatch
|
||||
|
||||
if breakpoint.expression is not None:
|
||||
try:
|
||||
try:
|
||||
val = eval(breakpoint.expression, new_frame.f_globals, new_frame.f_locals)
|
||||
except:
|
||||
val = sys.exc_info()[1]
|
||||
finally:
|
||||
if val is not None:
|
||||
info.pydev_message = str(val)
|
||||
handle_breakpoint_expression(breakpoint, info, new_frame)
|
||||
|
||||
if not main_debugger.first_breakpoint_reached:
|
||||
if is_call:
|
||||
@@ -696,7 +705,7 @@ class PyDBFrame:
|
||||
else:
|
||||
stop = False
|
||||
|
||||
if step_cmd != -1 and is_return and IS_PY3K and hasattr(frame, "f_back"):
|
||||
if stop and step_cmd != -1 and is_return and IS_PY3K and hasattr(frame, "f_back"):
|
||||
f_code = getattr(frame.f_back, 'f_code', None)
|
||||
if f_code is not None:
|
||||
back_filename = os.path.basename(f_code.co_filename)
|
||||
|
||||
@@ -17,7 +17,7 @@ from _pydevd_bundle.pydevd_comm import CMD_RUN, CMD_VERSION, CMD_LIST_THREADS, C
|
||||
CMD_REMOVE_EXCEPTION_BREAK, CMD_LOAD_SOURCE, CMD_ADD_DJANGO_EXCEPTION_BREAK, CMD_REMOVE_DJANGO_EXCEPTION_BREAK, \
|
||||
CMD_EVALUATE_CONSOLE_EXPRESSION, InternalEvaluateConsoleExpression, InternalConsoleGetCompletions, \
|
||||
CMD_RUN_CUSTOM_OPERATION, InternalRunCustomOperation, CMD_IGNORE_THROWN_EXCEPTION_AT, CMD_ENABLE_DONT_TRACE, \
|
||||
CMD_SHOW_RETURN_VALUES, ID_TO_MEANING, CMD_GET_DESCRIPTION, InternalGetDescription, enable_tracing_in_frames
|
||||
CMD_SHOW_RETURN_VALUES, ID_TO_MEANING, CMD_GET_DESCRIPTION, InternalGetDescription
|
||||
from _pydevd_bundle.pydevd_constants import get_thread_id, IS_PY3K, DebugInfoHolder, dict_contains, dict_keys, \
|
||||
STATE_RUN
|
||||
|
||||
@@ -326,9 +326,8 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
if py_db.plugin is not None:
|
||||
py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()
|
||||
|
||||
py_db.set_tracing_for_untraced_contexts(overwrite_prev_trace=True)
|
||||
if py_db.frame_eval_func is not None:
|
||||
enable_tracing_in_frames(py_db)
|
||||
py_db.set_tracing_for_untraced_contexts_if_not_frame_eval(overwrite_prev_trace=True)
|
||||
py_db.enable_tracing_in_frames_while_running_if_frame_eval()
|
||||
|
||||
elif cmd_id == CMD_REMOVE_BREAK:
|
||||
#command to remove some breakpoint
|
||||
@@ -445,6 +444,8 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
added.append(exception_breakpoint)
|
||||
|
||||
py_db.update_after_exceptions_added(added)
|
||||
if break_on_caught:
|
||||
py_db.enable_tracing_in_frames_while_running_if_frame_eval()
|
||||
|
||||
else:
|
||||
sys.stderr.write("Error when setting exception list. Received: %s\n" % (text,))
|
||||
@@ -515,6 +516,8 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
|
||||
if exception_breakpoint is not None:
|
||||
py_db.update_after_exceptions_added([exception_breakpoint])
|
||||
if notify_always:
|
||||
py_db.enable_tracing_in_frames_while_running_if_frame_eval()
|
||||
else:
|
||||
supported_type = False
|
||||
plugin = py_db.get_plugin_lazy_init()
|
||||
@@ -523,6 +526,7 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
|
||||
if supported_type:
|
||||
py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
|
||||
py_db.enable_tracing_in_frames_while_running_if_frame_eval()
|
||||
else:
|
||||
raise NameError(breakpoint_type)
|
||||
|
||||
@@ -560,6 +564,8 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
|
||||
else:
|
||||
raise NameError(exception_type)
|
||||
if len(py_db.break_on_caught_exceptions) == 0 and not py_db.has_plugin_exception_breaks:
|
||||
py_db.disable_tracing_while_running_if_frame_eval()
|
||||
|
||||
elif cmd_id == CMD_LOAD_SOURCE:
|
||||
path = text
|
||||
@@ -576,7 +582,7 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
if plugin is not None:
|
||||
plugin.add_breakpoint('add_exception_breakpoint', py_db, 'django', exception)
|
||||
py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
|
||||
|
||||
py_db.enable_tracing_in_frames_while_running_if_frame_eval()
|
||||
|
||||
elif cmd_id == CMD_REMOVE_DJANGO_EXCEPTION_BREAK:
|
||||
exception = text
|
||||
@@ -587,6 +593,8 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
if plugin is not None:
|
||||
plugin.remove_exception_breakpoint(py_db, 'django', exception)
|
||||
py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
|
||||
if len(py_db.break_on_caught_exceptions) == 0 and not py_db.has_plugin_exception_breaks:
|
||||
py_db.disable_tracing_while_running_if_frame_eval()
|
||||
|
||||
elif cmd_id == CMD_EVALUATE_CONSOLE_EXPRESSION:
|
||||
# Command which takes care for the debug console communication
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from _pydevd_bundle.pydevd_constants import get_frame
|
||||
from _pydev_imps._pydev_saved_modules import thread
|
||||
from _pydev_imps._pydev_saved_modules import thread, threading
|
||||
|
||||
try:
|
||||
import cStringIO as StringIO #may not always be available @UnusedImport
|
||||
@@ -97,4 +97,32 @@ def restore_sys_set_trace_func():
|
||||
sys.settrace = TracingFunctionHolder._original_tracing
|
||||
TracingFunctionHolder._original_tracing = None
|
||||
|
||||
|
||||
def settrace_while_running_if_frame_eval(py_db, trace_func):
|
||||
if not py_db.ready_to_run:
|
||||
# do it if only debug session is started
|
||||
return
|
||||
|
||||
if py_db.frame_eval_func is None:
|
||||
return
|
||||
|
||||
threads = threading.enumerate()
|
||||
try:
|
||||
for t in threads:
|
||||
if getattr(t, 'is_pydev_daemon_thread', False):
|
||||
continue
|
||||
additional_info = None
|
||||
try:
|
||||
additional_info = t.additional_info
|
||||
except AttributeError:
|
||||
pass # that's ok, no info currently set
|
||||
if additional_info is None:
|
||||
continue
|
||||
|
||||
for frame in additional_info.iter_frames(t):
|
||||
py_db.set_trace_for_frame_and_parents(frame, overwrite_prev_trace=True, dispatch_func=trace_func)
|
||||
py_db.enable_cache_frames_without_breaks(False)
|
||||
# sometimes (when script enters new frames too fast), we can't enable tracing only in the appropriate
|
||||
# frame. So, if breakpoint was added during run, we should disable frame evaluation forever.
|
||||
py_db.do_not_use_frame_eval = True
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
try:
|
||||
from _pydevd_frame_eval.pydevd_frame_evaluator import frame_eval_func, stop_frame_eval, set_use_code_extra, dummy_trace_dispatch
|
||||
from _pydevd_frame_eval.pydevd_frame_evaluator import frame_eval_func, stop_frame_eval, enable_cache_frames_without_breaks, dummy_trace_dispatch
|
||||
except ImportError:
|
||||
try:
|
||||
import struct
|
||||
@@ -15,8 +15,8 @@ except ImportError:
|
||||
|
||||
# We also accept things as:
|
||||
#
|
||||
# _pydevd_bundle.pydevd_cython_win32_27_32
|
||||
# _pydevd_bundle.pydevd_cython_win32_34_64
|
||||
# _pydevd_frame_eval.pydevd_frame_evaluator_win32_27_32
|
||||
# _pydevd_frame_eval.pydevd_frame_evaluator_win32_34_64
|
||||
#
|
||||
# to have multiple pre-compiled pyds distributed along the IDE
|
||||
# (generated by build_tools/build_binaries_windows.py).
|
||||
@@ -25,7 +25,7 @@ except ImportError:
|
||||
check_name = '_pydevd_frame_eval.%s' % (mod_name,)
|
||||
mod = __import__(check_name)
|
||||
mod = getattr(mod, mod_name)
|
||||
frame_eval_func, stop_frame_eval, set_use_code_extra, dummy_trace_dispatch =\
|
||||
mod.frame_eval_func, mod.stop_frame_eval, mod.set_use_code_extra, mod.dummy_trace_dispatch
|
||||
frame_eval_func, stop_frame_eval, enable_cache_frames_without_breaks, dummy_trace_dispatch =\
|
||||
mod.frame_eval_func, mod.stop_frame_eval, mod.enable_cache_frames_without_breaks, mod.dummy_trace_dispatch
|
||||
except ImportError:
|
||||
raise
|
||||
@@ -7,7 +7,7 @@ if sys.version_info[0] == 3 and sys.version_info[1] == 6:
|
||||
|
||||
frame_eval_func = None
|
||||
stop_frame_eval = None
|
||||
set_use_code_extra = None
|
||||
enable_cache_frames_without_breaks = None
|
||||
dummy_trace_dispatch = None
|
||||
|
||||
USE_FRAME_EVAL = os.environ.get('PYDEVD_USE_FRAME_EVAL', None)
|
||||
@@ -18,7 +18,7 @@ if USE_FRAME_EVAL == 'NO':
|
||||
else:
|
||||
if IS_PY36:
|
||||
try:
|
||||
from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import frame_eval_func, stop_frame_eval, set_use_code_extra, \
|
||||
from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import frame_eval_func, stop_frame_eval, enable_cache_frames_without_breaks, \
|
||||
dummy_trace_dispatch
|
||||
except ImportError:
|
||||
from _pydev_bundle.pydev_monkey import log_error_once
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,8 @@ def is_use_code_extra():
|
||||
return UseCodeExtraHolder.use_code_extra
|
||||
|
||||
|
||||
def set_use_code_extra(new_value):
|
||||
# enable using `co_extra` field in order to cache frames without breakpoints
|
||||
def enable_cache_frames_without_breaks(new_value):
|
||||
UseCodeExtraHolder.use_code_extra = new_value
|
||||
|
||||
|
||||
@@ -125,7 +126,7 @@ cdef PyObject* get_bytecode_while_frame_eval(PyFrameObject *frame_obj, int exc):
|
||||
if was_break:
|
||||
update_globals_dict(frame.f_globals)
|
||||
for bp in breakpoints_to_update:
|
||||
bp.code_objects.append(frame.f_code)
|
||||
bp.code_objects.add(frame.f_code)
|
||||
else:
|
||||
if main_debugger.has_plugin_line_breaks:
|
||||
can_not_skip = main_debugger.plugin.can_not_skip(main_debugger, None, frame)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from _pydev_bundle import pydev_log
|
||||
from _pydev_imps._pydev_saved_modules import threading
|
||||
from _pydevd_bundle.pydevd_comm import get_global_debugger, CMD_SET_BREAK
|
||||
from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame, NORM_PATHS_AND_BASE_CONTAINER
|
||||
from _pydevd_bundle.pydevd_frame import handle_breakpoint_condition, handle_breakpoint_expression
|
||||
|
||||
|
||||
class DummyTracingHolder:
|
||||
@@ -28,47 +28,12 @@ def handle_breakpoint(frame, thread, global_debugger, breakpoint):
|
||||
condition = breakpoint.condition
|
||||
info = thread.additional_info
|
||||
if condition is not None:
|
||||
try:
|
||||
val = eval(condition, new_frame.f_globals, new_frame.f_locals)
|
||||
if not val:
|
||||
return False
|
||||
|
||||
except:
|
||||
if type(condition) != type(''):
|
||||
if hasattr(condition, 'encode'):
|
||||
condition = condition.encode('utf-8')
|
||||
|
||||
msg = 'Error while evaluating expression: %s\n' % (condition,)
|
||||
sys.stderr.write(msg)
|
||||
traceback.print_exc()
|
||||
if not global_debugger.suspend_on_breakpoint_exception:
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
# add exception_type and stacktrace into thread additional info
|
||||
etype, value, tb = sys.exc_info()
|
||||
try:
|
||||
error = ''.join(traceback.format_exception_only(etype, value))
|
||||
stack = traceback.extract_stack(f=tb.tb_frame.f_back)
|
||||
|
||||
# On self.set_suspend(thread, CMD_SET_BREAK) this info will be
|
||||
# sent to the client.
|
||||
info.conditional_breakpoint_exception = \
|
||||
('Condition:\n' + condition + '\n\nError:\n' + error, stack)
|
||||
finally:
|
||||
etype, value, tb = None, None, None
|
||||
except:
|
||||
traceback.print_exc()
|
||||
eval_result = handle_breakpoint_condition(global_debugger, info, breakpoint, new_frame)
|
||||
if not eval_result:
|
||||
return False
|
||||
|
||||
if breakpoint.expression is not None:
|
||||
try:
|
||||
try:
|
||||
val = eval(breakpoint.expression, new_frame.f_globals, new_frame.f_locals)
|
||||
except:
|
||||
val = sys.exc_info()[1]
|
||||
finally:
|
||||
if val is not None:
|
||||
info.pydev_message = str(val)
|
||||
handle_breakpoint_expression(breakpoint, info, new_frame)
|
||||
|
||||
if breakpoint.suspend_policy == "ALL":
|
||||
global_debugger.suspend_all_other_threads(thread)
|
||||
|
||||
@@ -36,7 +36,7 @@ from _pydevd_bundle.pydevd_custom_frames import CustomFramesContainer, custom_fr
|
||||
from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame
|
||||
from _pydevd_bundle.pydevd_kill_all_pydevd_threads import kill_all_pydev_threads
|
||||
from _pydevd_bundle.pydevd_trace_dispatch import trace_dispatch as _trace_dispatch, global_cache_skips, global_cache_frame_skips
|
||||
from _pydevd_frame_eval.pydevd_frame_eval_main import frame_eval_func, stop_frame_eval, set_use_code_extra, dummy_trace_dispatch
|
||||
from _pydevd_frame_eval.pydevd_frame_eval_main import frame_eval_func, stop_frame_eval, enable_cache_frames_without_breaks, dummy_trace_dispatch
|
||||
from _pydevd_bundle.pydevd_utils import save_main_module
|
||||
from pydevd_concurrency_analyser.pydevd_concurrency_logger import ThreadingLogger, AsyncioLogger, send_message, cur_time
|
||||
from pydevd_concurrency_analyser.pydevd_thread_wrappers import wrap_threads
|
||||
@@ -255,6 +255,9 @@ class PyDB:
|
||||
self.show_return_values = False
|
||||
self.remove_return_values_flag = False
|
||||
|
||||
# this flag disables frame evaluation even if it's available
|
||||
self.do_not_use_frame_eval = False
|
||||
|
||||
def get_plugin_lazy_init(self):
|
||||
if self.plugin is None and SUPPORT_PLUGINS:
|
||||
self.plugin = PluginManager(self)
|
||||
@@ -552,6 +555,16 @@ class PyDB:
|
||||
finally:
|
||||
self._main_lock.release()
|
||||
|
||||
def disable_tracing_while_running_if_frame_eval(self):
|
||||
pydevd_tracing.settrace_while_running_if_frame_eval(self, self.dummy_trace_dispatch)
|
||||
|
||||
def enable_tracing_in_frames_while_running_if_frame_eval(self):
|
||||
pydevd_tracing.settrace_while_running_if_frame_eval(self, self.trace_dispatch)
|
||||
|
||||
def set_tracing_for_untraced_contexts_if_not_frame_eval(self, ignore_frame=None, overwrite_prev_trace=False):
|
||||
if self.frame_eval_func is not None:
|
||||
return
|
||||
self.set_tracing_for_untraced_contexts(ignore_frame, overwrite_prev_trace)
|
||||
|
||||
def set_tracing_for_untraced_contexts(self, ignore_frame=None, overwrite_prev_trace=False):
|
||||
# Enable the tracing for existing threads (because there may be frames being executed that
|
||||
@@ -639,8 +652,7 @@ class PyDB:
|
||||
|
||||
if not updated_on_caught and eb.notify_always:
|
||||
updated_on_caught = True
|
||||
self.set_tracing_for_untraced_contexts()
|
||||
|
||||
self.set_tracing_for_untraced_contexts_if_not_frame_eval()
|
||||
|
||||
def _process_thread_not_alive(self, threadId):
|
||||
""" if thread is not alive, cancel trace_dispatch processing """
|
||||
@@ -813,9 +825,12 @@ class PyDB:
|
||||
info.pydev_state = STATE_RUN
|
||||
|
||||
if self.frame_eval_func is not None and info.pydev_state == STATE_RUN:
|
||||
if info.pydev_step_cmd != -1:
|
||||
if info.pydev_step_cmd == CMD_STEP_INTO or info.pydev_step_cmd == CMD_STEP_INTO_MY_CODE:
|
||||
self.set_trace_for_frame_and_parents(frame)
|
||||
if info.pydev_step_cmd == -1:
|
||||
if not self.do_not_use_frame_eval:
|
||||
self.SetTrace(self.dummy_trace_dispatch)
|
||||
self.set_trace_for_frame_and_parents(frame, overwrite_prev_trace=True, dispatch_func=dummy_trace_dispatch)
|
||||
else:
|
||||
self.set_trace_for_frame_and_parents(frame, overwrite_prev_trace=True)
|
||||
# enable old tracing function for stepping
|
||||
self.SetTrace(self.trace_dispatch)
|
||||
|
||||
@@ -1042,7 +1057,7 @@ class PyDB:
|
||||
trace_dispatch = _trace_dispatch
|
||||
frame_eval_func = frame_eval_func
|
||||
dummy_trace_dispatch = dummy_trace_dispatch
|
||||
set_use_code_extra = set_use_code_extra
|
||||
enable_cache_frames_without_breaks = enable_cache_frames_without_breaks
|
||||
|
||||
def set_debug(setup):
|
||||
setup['DEBUG_RECORD_SOCKET_READS'] = True
|
||||
@@ -1211,13 +1226,14 @@ def _locked_settrace(
|
||||
time.sleep(0.1) # busy wait until we receive run command
|
||||
|
||||
global forked
|
||||
frame_eval_for_tracing = debugger.frame_eval_func
|
||||
if frame_eval_func is not None and not forked:
|
||||
# Disable frame evaluation for Remote Debug Server
|
||||
debugger.frame_eval_func = None
|
||||
frame_eval_for_tracing = None
|
||||
|
||||
# note that we do that through pydevd_tracing.SetTrace so that the tracing
|
||||
# is not warned to the user!
|
||||
pydevd_tracing.SetTrace(debugger.trace_dispatch, debugger.frame_eval_func, debugger.dummy_trace_dispatch)
|
||||
pydevd_tracing.SetTrace(debugger.trace_dispatch, frame_eval_for_tracing, debugger.dummy_trace_dispatch)
|
||||
|
||||
if not trace_only_current_thread:
|
||||
# Trace future threads?
|
||||
|
||||
@@ -46,7 +46,7 @@ def add_exception_breakpoint(plugin, pydb, type, exception):
|
||||
if not hasattr(pydb, 'django_exception_break'):
|
||||
_init_plugin_breaks(pydb)
|
||||
pydb.django_exception_break[exception] = True
|
||||
pydb.set_tracing_for_untraced_contexts()
|
||||
pydb.set_tracing_for_untraced_contexts_if_not_frame_eval()
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def add_exception_breakpoint(plugin, pydb, type, exception):
|
||||
if not hasattr(pydb, 'jinja2_exception_break'):
|
||||
_init_plugin_breaks(pydb)
|
||||
pydb.jinja2_exception_break[exception] = True
|
||||
pydb.set_tracing_for_untraced_contexts()
|
||||
pydb.set_tracing_for_untraced_contexts_if_not_frame_eval()
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
i = 0
|
||||
while True:
|
||||
print(i)
|
||||
i = i + 1
|
||||
print(i)
|
||||
i = i + 1
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
from time import sleep
|
||||
|
||||
|
||||
def foo(x):
|
||||
print(x)
|
||||
|
||||
x = 0
|
||||
print(x)
|
||||
while x < 2:
|
||||
x += 1
|
||||
foo(x)
|
||||
while x<2:
|
||||
x+=1
|
||||
print(x)
|
||||
|
||||
x += 10
|
||||
x+=10
|
||||
print("x = %d" % x)
|
||||
while True:
|
||||
sleep(0.1)
|
||||
sleep(0.1)
|
||||
@@ -647,7 +647,7 @@ public class PythonDebuggerTest extends PyEnvTestCase {
|
||||
@Test
|
||||
@StagingOn(os = TestEnv.WINDOWS)
|
||||
public void testWinLongName() throws Exception {
|
||||
if (UsefulTestCase.IS_UNDER_TEAMCITY && !SystemInfo.isWindows) {
|
||||
if (!SystemInfo.isWindows) {
|
||||
return; // Only needs to run on windows
|
||||
}
|
||||
runPythonTest(new PyDebuggerTask("/debug", "long_n~1.py") {
|
||||
|
||||
Reference in New Issue
Block a user