def do_connect_to_debugger(): try: # Try to import the packages needed to attach the debugger import pydevd from _pydev_imps._pydev_saved_modules import threading except: # This happens on Jython embedded in host eclipse traceback.print_exc() sys.stderr.write('pydevd is not available, cannot connect\n',) from _pydev_bundle import pydev_localhost threading.currentThread().__pydevd_id__ = "console_main" self.orig_find_frame = pydevd_vars.find_frame pydevd_vars.find_frame = self._findFrame self.debugger = pydevd.PyDB() try: self.debugger.connect(pydev_localhost.get_localhost(), debuggerPort) self.debugger.prepare_to_run() import pydevd_tracing pydevd_tracing.SetTrace(None) except: traceback.print_exc() sys.stderr.write('Failed to connect to target debugger.\n') # Register to process commands when idle self.debugrunning = False try: import pydevconsole pydevconsole.set_debug_hook(self.debugger.process_internal_commands) except: traceback.print_exc() sys.stderr.write('Version of Python does not support debuggable Interactive Console.\n')
def __call__(self): # We monkey-patch the thread creation so that this function is called in the new thread. At this point # we notify of its creation and start tracing it. global_debugger = get_global_debugger() thread_id = None if global_debugger is not None: # Note: if this is a thread from threading.py, we're too early in the boostrap process (because we mocked # the start_new_thread internal machinery and thread._bootstrap has not finished), so, the code below needs # to make sure that we use the current thread bound to the original function and not use # threading.currentThread() unless we're sure it's a dummy thread. t = getattr(self.original_func, '__self__', getattr(self.original_func, 'im_self', None)) if not isinstance(t, threading.Thread): # This is not a threading.Thread but a Dummy thread (so, get it as a dummy thread using # currentThread). t = threading.currentThread() if not getattr(t, 'is_pydev_daemon_thread', False): thread_id = get_thread_id(t) global_debugger.notify_thread_created(thread_id, t) _on_set_trace_for_new_thread(global_debugger) if getattr(global_debugger, 'thread_analyser', None) is not None: try: from pydevd_concurrency_analyser.pydevd_concurrency_logger import log_new_thread log_new_thread(global_debugger, t) except: sys.stderr.write("Failed to detect new thread for visualization") try: ret = self.original_func(*self.args, **self.kwargs) finally: if thread_id is not None: global_debugger.notify_thread_not_alive(thread_id) return ret
def start_client(host, port): #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit from pydev_console.protocol import PythonConsoleBackendService, PythonConsoleFrontendService enable_thrift_logging() client_service = PythonConsoleFrontendService client, server_transport = make_rpc_client(client_service, host, port) interpreter = InterpreterInterface(threading.currentThread(), rpc_client=client) # we do not need to start the server in a new thread because it does not need to accept a client connection, it already has it # Tell UMD the proper default namespace _set_globals_function(interpreter.get_namespace) server_service = PythonConsoleBackendService # `InterpreterInterface` implements all methods required for the handler server_handler = interpreter start_rpc_server(server_transport, server_service, server_handler) process_exec_queue(interpreter)
def _pydev_stop_at_break(): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False if t.additional_info.pydev_step_cmd == -1 and frame.f_trace in (None, dummy_tracing_holder.dummy_trace_func): # do not handle breakpoints while stepping, because they're handled by old tracing function t.additional_info.is_tracing = True debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame(frame) filename = abs_path_real_path_and_base[1] breakpoints_for_file = debugger.breakpoints.get(filename) line = _get_line_for_frame(frame) try: breakpoint = breakpoints_for_file[line] except KeyError: pydev_log.debug("Couldn't find breakpoint in the file {} on line {}".format(frame.f_code.co_filename, line)) t.additional_info.is_tracing = False return False if breakpoint and handle_breakpoint(frame, t, debugger, breakpoint): pydev_log.debug("Suspending at breakpoint in file: {} on line {}".format(frame.f_code.co_filename, line)) debugger.set_suspend(t, CMD_SET_BREAK) debugger.do_wait_suspend(t, frame, 'line', None, "frame_eval") t.additional_info.is_tracing = False return t.additional_info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT return False
def add_custom_frame(frame, name, thread_id): ''' It's possible to show paused frames by adding a custom frame through this API (it's intended to be used for coroutines, but could potentially be used for generators too). :param frame: The topmost frame to be shown paused when a thread with thread.ident == thread_id is paused. :param name: The name to be shown for the custom thread in the UI. :param thread_id: The thread id to which this frame is related (must match thread.ident). :return: str Returns the custom thread id which will be used to show the given frame paused. ''' with CustomFramesContainer.custom_frames_lock: curr_thread_id = get_current_thread_id(threading.currentThread()) next_id = CustomFramesContainer._next_frame_id = CustomFramesContainer._next_frame_id + 1 # Note: the frame id kept contains an id and thread information on the thread where the frame was added # so that later on we can check if the frame is from the current thread by doing frame_id.endswith('|'+thread_id). frame_custom_thread_id = '__frame__:%s|%s' % (next_id, curr_thread_id) if DEBUG: sys.stderr.write('add_custom_frame: %s (%s) %s %s\n' % ( frame_custom_thread_id, get_abs_path_real_path_and_base_from_frame(frame)[-1], frame.f_lineno, frame.f_code.co_name)) CustomFramesContainer.custom_frames[frame_custom_thread_id] = CustomFrame(name, frame, thread_id) CustomFramesContainer._py_db_command_thread_event.set() return frame_custom_thread_id
def start_server(port): if port is None: port = 0 # 0. General stuff #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit from pydev_console.protocol import PythonConsoleBackendService, PythonConsoleFrontendService enable_thrift_logging() server_service = PythonConsoleBackendService client_service = PythonConsoleFrontendService # 1. Start Python console server # `InterpreterInterface` implements all methods required for `server_handler` interpreter = InterpreterInterface(threading.currentThread()) # Tell UMD the proper default namespace _set_globals_function(interpreter.get_namespace) server_socket = start_rpc_server_and_make_client('', port, server_service, client_service, create_server_handler_factory(interpreter)) # 2. Print server port for the IDE _, server_port = server_socket.getsockname() print(server_port) # 3. Wait for IDE to connect to the server process_exec_queue(interpreter)
def get_interpreter(): try: interpreterInterface = getattr(__builtin__, 'interpreter') except AttributeError: interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) setattr(__builtin__, 'interpreter', interpreterInterface) return interpreterInterface
def dump_frames(thread_id): sys.stdout.write('dumping frames\n') if thread_id != get_thread_id(threading.currentThread()): raise VariableError("find_frame: must execute on same thread") curFrame = get_frame() for frame in _iter_frames(curFrame): sys.stdout.write('%s\n' % pickle.dumps(frame))
def get_interpreter(): try: interpreterInterface = getattr(__builtin__, 'interpreter') except AttributeError: interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) __builtin__.interpreter = interpreterInterface print(interpreterInterface.get_greeting_msg()) return interpreterInterface
def start_server(host, port, client_port): #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit interpreter = InterpreterInterface(host, client_port, threading.currentThread()) start_new_thread(start_console_server,(host, port, interpreter)) process_exec_queue(interpreter)
def get_interpreter(): try: interpreterInterface = getattr(__builtin__, 'interpreter') except AttributeError: interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) __builtin__.interpreter = interpreterInterface print(interpreterInterface.get_greeting_msg()) return interpreterInterface
def get_interpreter(): try: interpreterInterface = getattr(__builtin__, 'interpreter') except AttributeError: interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) setattr(__builtin__, 'interpreter', interpreterInterface) sys.stderr.write(interpreterInterface.get_greeting_msg()) sys.stderr.flush() return interpreterInterface
def get_interpreter(): try: interpreterInterface = getattr(__builtin__, 'interpreter') except AttributeError: interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) setattr(__builtin__, 'interpreter', interpreterInterface) sys.stderr.write(interpreterInterface.get_greeting_msg()) sys.stderr.flush() return interpreterInterface
def start_server(host, port, client_port): #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit interpreter = InterpreterInterface(host, client_port, threading.currentThread()) start_new_thread(start_console_server,(host, port, interpreter)) process_exec_queue(interpreter)
def __call__(self): # We monkey-patch the thread creation so that this function is called in the new thread. At this point # we notify of its creation and start tracing it. global_debugger = get_global_debugger() thread_id = None if global_debugger is not None: # Note: if this is a thread from threading.py, we're too early in the boostrap process (because we mocked # the start_new_thread internal machinery and thread._bootstrap has not finished), so, the code below needs # to make sure that we use the current thread bound to the original function and not use # threading.currentThread() unless we're sure it's a dummy thread. t = getattr(self.original_func, '__self__', getattr(self.original_func, 'im_self', None)) if not isinstance(t, threading.Thread): # This is not a threading.Thread but a Dummy thread (so, get it as a dummy thread using # currentThread). t = threading.currentThread() if not getattr(t, 'is_pydev_daemon_thread', False): thread_id = get_current_thread_id(t) global_debugger.notify_thread_created(thread_id, t) _on_set_trace_for_new_thread(global_debugger) if getattr(global_debugger, 'thread_analyser', None) is not None: try: from pydevd_concurrency_analyser.pydevd_concurrency_logger import log_new_thread log_new_thread(global_debugger, t) except: sys.stderr.write( "Failed to detect new thread for visualization") try: try: ret = self.original_func(*self.args, **self.kwargs) except: # If threads die with the debugger alive, it's possible that we # have exceptions during teardown (Python goes through each module # and sets their attributes to None). In this situation, don't # report spurious exceptions because of that. if sys is None or pydevd_tracing is None: return finally: if sys is None or pydevd_tracing is None: return else: if thread_id is not None and global_debugger is not None: global_debugger.notify_thread_not_alive(thread_id) frame = sys._getframe() while frame is not None: if frame.f_trace is not None: frame.f_trace = NO_FTRACE frame = frame.f_back pydevd_tracing.SetTrace(None) return ret
def _do_not_trace_ctx(): current_thread = threading.currentThread() do_not_trace_before = getattr(current_thread, 'pydev_do_not_trace', None) if do_not_trace_before: yield return current_thread.pydev_do_not_trace = True try: yield finally: current_thread.pydev_do_not_trace = do_not_trace_before
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing = True try: debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) filename = abs_path_real_path_and_base[1] breakpoints_for_file = debugger.breakpoints.get(filename) try: python_breakpoint = breakpoints_for_file[line] except KeyError: pydev_log.debug( "Couldn't find breakpoint in the file {} on line {}".format( frame.f_code.co_filename, line)) return if python_breakpoint: pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules[ '_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: debugger = get_global_debugger() frame.f_trace = debugger.get_thread_local_trace_func() # For bytecode patching issue diagnosis. Can make the debugger really slow. if os.environ.get( 'PYDEVD_TRACE_OPCODES') == 'True' and IS_PY37_OR_GREATER: frame.f_trace_opcodes = True finally: t.additional_info.is_tracing = False
def _fallback_excepthook(exctype, value, tb): pydev_log.debug("Handling the uncaught exception in the fallback exception hook") try: debugger = get_global_debugger() if debugger and debugger.break_on_uncaught_exceptions: thread = threading.currentThread() additional_info = getattr(thread, 'additional_info', None) if not thread or additional_info is None: return debugger.disable_tracing() stop_on_unhandled_exception(debugger, thread, additional_info, (exctype, value, tb)) finally: if sys.excepthook != dummy_excepthook: original_excepthook(exctype, value, tb) sys.exit(1)
def do_connect_to_debugger(): try: # Try to import the packages needed to attach the debugger import pydevd from _pydev_imps._pydev_saved_modules import threading except: # This happens on Jython embedded in host eclipse traceback.print_exc() sys.stderr.write('pydevd is not available, cannot connect\n', ) from _pydevd_bundle.pydevd_constants import set_thread_id from _pydev_bundle import pydev_localhost set_thread_id(threading.currentThread(), "console_main") VIRTUAL_FRAME_ID = "1" # matches PyStackFrameConsole.java VIRTUAL_CONSOLE_ID = "console_main" # matches PyThreadConsole.java f = FakeFrame() f.f_back = None f.f_globals = { } # As globals=locals here, let's simply let it empty (and save a bit of network traffic). f.f_locals = self.get_namespace() self.debugger = pydevd.PyDB() self.debugger.add_fake_frame(thread_id=VIRTUAL_CONSOLE_ID, frame_id=VIRTUAL_FRAME_ID, frame=f) try: pydevd.apply_debugger_options(debugger_options) self.debugger.connect(pydev_localhost.get_localhost(), debuggerPort) self.debugger.prepare_to_run() self.debugger.disable_tracing() except: traceback.print_exc() sys.stderr.write('Failed to connect to target debugger.\n') # Register to process commands when idle self.debugrunning = False try: import pydevconsole pydevconsole.set_debug_hook( self.debugger.process_internal_commands) except: traceback.print_exc() sys.stderr.write( 'Version of Python does not support debuggable Interactive Console.\n' )
def suspend_at_builtin_breakpoint(): # used by built-in breakpoint() function appeared in Python 3.7 frame = sys._getframe(3) t = threading.currentThread() if t.additional_info.is_tracing: return False if t.additional_info.pydev_step_cmd == -1: # do not handle breakpoints while stepping, because they're handled by old tracing function t.additional_info.is_tracing = True pydev_log.debug("Suspending at breakpoint in file: {} on line {}".format(frame.f_code.co_filename, frame.f_lineno)) debugger = get_global_debugger() debugger.set_suspend(t, CMD_SET_BREAK) debugger.do_wait_suspend(t, frame, 'line', None, "frame_eval") t.additional_info.is_tracing = False return t.additional_info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT return False
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing += 1 try: py_db = get_global_debugger() if py_db is None: return try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) filename = abs_path_real_path_and_base[1] try: python_breakpoint = py_db.breakpoints[filename][line] except: # print("Couldn't find breakpoint in the file %s on line %s" % (frame.f_code.co_filename, line)) # Could be KeyError if line is not there or TypeError if breakpoints_for_file is None. # Note: using catch-all exception for performance reasons (if the user adds a breakpoint # and then removes it after hitting it once, this method added for the programmatic # breakpoint will keep on being called and one of those exceptions will always be raised # here). return if python_breakpoint: pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules[ '_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: frame.f_trace = py_db.get_thread_local_trace_func() finally: t.additional_info.is_tracing -= 1
def suspend_at_builtin_breakpoint(): # used by built-in breakpoint() function appeared in Python 3.7 frame = sys._getframe(3) t = threading.currentThread() if t.additional_info.is_tracing: return False if t.additional_info.pydev_step_cmd == -1: # do not handle breakpoints while stepping, because they're handled by old tracing function t.additional_info.is_tracing = True pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, frame.f_lineno)) debugger = get_global_debugger() debugger.set_suspend(t, CMD_SET_BREAK) debugger.do_wait_suspend(t, frame, 'line', None, "frame_eval") frame.f_trace = debugger.get_thread_local_trace_func() t.additional_info.is_tracing = False
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing = True try: debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) filename = abs_path_real_path_and_base[1] breakpoints_for_file = debugger.breakpoints.get(filename) try: python_breakpoint = breakpoints_for_file[line] except KeyError: pydev_log.debug( "Couldn't find breakpoint in the file {} on line {}".format( frame.f_code.co_filename, line)) return if python_breakpoint: pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules[ '_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: debugger = get_global_debugger() frame.f_trace = debugger.get_thread_local_trace_func() finally: t.additional_info.is_tracing = False
def do_connect_to_debugger(): try: # Try to import the packages needed to attach the debugger import pydevd from _pydev_imps._pydev_saved_modules import threading except: # This happens on Jython embedded in host eclipse traceback.print_exc() sys.stderr.write( 'pydevd is not available, cannot connect\n', ) from _pydevd_bundle.pydevd_constants import set_thread_id from _pydev_bundle import pydev_localhost set_thread_id(threading.currentThread(), "console_main") self.orig_find_frame = pydevd_vars.find_frame pydevd_vars.find_frame = self._findFrame self.debugger = pydevd.PyDB() try: pydevd.apply_debugger_options(debugger_options) if debugger_host is None or pydev_localhost.is_localhost( debugger_host): host = pydev_localhost.get_localhost() else: host = debugger_host self.debugger.connect(host, debuggerPort) self.debugger.prepare_to_run() self.debugger.disable_tracing() except: traceback.print_exc() sys.stderr.write('Failed to connect to target debugger.\n') # Register to process commands when idle self.debugrunning = False try: import pydevconsole pydevconsole.set_debug_hook( self.debugger.process_internal_commands) except: traceback.print_exc() sys.stderr.write( 'Version of Python does not support debuggable Interactive Console.\n' )
def add_custom_frame(frame, name, thread_id): CustomFramesContainer.custom_frames_lock.acquire() try: curr_thread_id = get_current_thread_id(threading.currentThread()) next_id = CustomFramesContainer._next_frame_id = CustomFramesContainer._next_frame_id + 1 # Note: the frame id kept contains an id and thread information on the thread where the frame was added # so that later on we can check if the frame is from the current thread by doing frame_id.endswith('|'+thread_id). frame_id = '__frame__:%s|%s' % (next_id, curr_thread_id) if DEBUG: sys.stderr.write('add_custom_frame: %s (%s) %s %s\n' % ( frame_id, get_abs_path_real_path_and_base_from_frame(frame)[-1], frame.f_lineno, frame.f_code.co_name)) CustomFramesContainer.custom_frames[frame_id] = CustomFrame(name, frame, thread_id) CustomFramesContainer._py_db_command_thread_event.set() return frame_id finally: CustomFramesContainer.custom_frames_lock.release()
def run(self): created_pydb_daemon = self.created_pydb_daemon_threads created_pydb_daemon[self] = 1 try: try: if IS_JYTHON and not isinstance(threading.currentThread(), threading._MainThread): # we shouldn't update sys.modules for the main thread, cause it leads to the second importing 'threading' # module, and the new instance of main thread is created ss = JyCore.PySystemState() # Note: Py.setSystemState() affects only the current thread. JyCore.Py.setSystemState(ss) self._stop_trace() self._on_run() except: if sys is not None and traceback is not None: traceback.print_exc() finally: del created_pydb_daemon[self]
def _pydev_stop_at_break(): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False if t.additional_info.pydev_step_cmd == -1 and frame.f_trace in ( None, dummy_tracing_holder.dummy_trace_func): # do not handle breakpoints while stepping, because they're handled by old tracing function t.additional_info.is_tracing = True debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) filename = abs_path_real_path_and_base[1] breakpoints_for_file = debugger.breakpoints.get(filename) line = _get_line_for_frame(frame) try: breakpoint = breakpoints_for_file[line] except KeyError: pydev_log.debug( "Couldn't find breakpoint in the file {} on line {}".format( frame.f_code.co_filename, line)) t.additional_info.is_tracing = False return False if breakpoint and handle_breakpoint(frame, t, debugger, breakpoint): pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, line)) debugger.set_suspend( t, CMD_SET_BREAK, suspend_other_threads=breakpoint.suspend_policy, ) debugger.do_wait_suspend(t, frame, 'line', None, "frame_eval") t.additional_info.is_tracing = False return t.additional_info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT return False
def SetTrace(tracing_func): if TracingFunctionHolder._original_tracing is None: #This may happen before replace_sys_set_trace_func is called. sys.settrace(tracing_func) return current_thread = threading.currentThread() do_not_trace_before = getattr(current_thread, 'pydev_do_not_trace', None) if do_not_trace_before: return try: TracingFunctionHolder._lock.acquire() current_thread.pydev_do_not_trace = True # avoid settrace reentering TracingFunctionHolder._warn = False _internal_set_trace(tracing_func) TracingFunctionHolder._warn = True finally: TracingFunctionHolder._lock.release() current_thread.pydev_do_not_trace = do_not_trace_before
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing = True try: debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame(frame) filename = abs_path_real_path_and_base[1] try: python_breakpoint = debugger.breakpoints[filename][line] except: # print("Couldn't find breakpoint in the file %s on line %s" % (frame.f_code.co_filename, line)) # Could be KeyError if line is not there or TypeError if breakpoints_for_file is None. # Note: using catch-all exception for performance reasons (if the user adds a breakpoint # and then removes it after hitting it once, this method added for the programmatic # breakpoint will keep on being called and one of those exceptions will always be raised # here). return if python_breakpoint: pydev_log.debug("Suspending at breakpoint in file: {} on line {}".format(frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules['_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: debugger = get_global_debugger() frame.f_trace = debugger.get_thread_local_trace_func() finally: t.additional_info.is_tracing = False
def do_connect_to_debugger(): try: # Try to import the packages needed to attach the debugger import pydevd from _pydev_imps._pydev_saved_modules import threading except: # This happens on Jython embedded in host eclipse traceback.print_exc() sys.stderr.write('pydevd is not available, cannot connect\n', ) from _pydevd_bundle.pydevd_constants import set_thread_id from _pydev_bundle import pydev_localhost set_thread_id(threading.currentThread(), "console_main") VIRTUAL_FRAME_ID = "1" # matches PyStackFrameConsole.java VIRTUAL_CONSOLE_ID = "console_main" # matches PyThreadConsole.java f = FakeFrame() f.f_back = None f.f_globals = {} # As globals=locals here, let's simply let it empty (and save a bit of network traffic). f.f_locals = self.get_namespace() self.debugger = pydevd.PyDB() self.debugger.add_fake_frame(thread_id=VIRTUAL_CONSOLE_ID, frame_id=VIRTUAL_FRAME_ID, frame=f) try: pydevd.apply_debugger_options(debugger_options) self.debugger.connect(pydev_localhost.get_localhost(), debuggerPort) self.debugger.prepare_to_run() self.debugger.disable_tracing() except: traceback.print_exc() sys.stderr.write('Failed to connect to target debugger.\n') # Register to process commands when idle self.debugrunning = False try: import pydevconsole pydevconsole.set_debug_hook(self.debugger.process_internal_commands) except: traceback.print_exc() sys.stderr.write('Version of Python does not support debuggable Interactive Console.\n')
def __call__(self): # We monkey-patch the thread creation so that this function is called in the new thread. At this point # we notify of its creation and start tracing it. py_db = get_global_debugger() thread_id = None if py_db is not None: # Note: if this is a thread from threading.py, we're too early in the boostrap process (because we mocked # the start_new_thread internal machinery and thread._bootstrap has not finished), so, the code below needs # to make sure that we use the current thread bound to the original function and not use # threading.currentThread() unless we're sure it's a dummy thread. t = getattr(self.original_func, '__self__', getattr(self.original_func, 'im_self', None)) if not isinstance(t, threading.Thread): # This is not a threading.Thread but a Dummy thread (so, get it as a dummy thread using # currentThread). t = threading.currentThread() if not getattr(t, 'is_pydev_daemon_thread', False): thread_id = get_current_thread_id(t) py_db.notify_thread_created(thread_id, t) _on_set_trace_for_new_thread(py_db) if getattr(py_db, 'thread_analyser', None) is not None: try: from pydevd_concurrency_analyser.pydevd_concurrency_logger import log_new_thread log_new_thread(py_db, t) except: sys.stderr.write( "Failed to detect new thread for visualization") try: ret = self.original_func(*self.args, **self.kwargs) finally: if thread_id is not None: if py_db is not None: # At thread shutdown we only have pydevd-related code running (which shouldn't # be tracked). py_db.disable_tracing() py_db.notify_thread_not_alive(thread_id) return ret
def start_server(port): if port is None: port = 0 # 0. General stuff #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit from pydev_console.protocol import PythonConsoleBackendService, PythonConsoleFrontendService enable_thrift_logging() server_service = PythonConsoleBackendService client_service = PythonConsoleFrontendService # 1. Start Python console server # `InterpreterInterface` implements all methods required for `server_handler` interpreter = InterpreterInterface(threading.currentThread()) # Tell UMD the proper default namespace _set_globals_function(interpreter.get_namespace) server_socket = start_rpc_server_and_make_client( '', port, server_service, client_service, create_server_handler_factory(interpreter)) # 2. Print server port for the IDE _, server_port = server_socket.getsockname() print(server_port) # 3. Wait for IDE to connect to the server process_exec_queue(interpreter)
def SetTrace(tracing_func, frame_eval_func=None, dummy_tracing_func=None): if tracing_func is not None and frame_eval_func is not None: # There is no need to set tracing function if frame evaluation is available frame_eval_func() tracing_func = dummy_tracing_func if TracingFunctionHolder._original_tracing is None: #This may happen before replace_sys_set_trace_func is called. sys.settrace(tracing_func) return current_thread = threading.currentThread() do_not_trace_before = getattr(current_thread, 'pydev_do_not_trace', None) if do_not_trace_before: return try: TracingFunctionHolder._lock.acquire() current_thread.pydev_do_not_trace = True # avoid settrace reentering TracingFunctionHolder._warn = False _internal_set_trace(tracing_func) TracingFunctionHolder._warn = True finally: TracingFunctionHolder._lock.release() current_thread.pydev_do_not_trace = do_not_trace_before
def SetTrace(tracing_func, frame_eval_func=None, dummy_tracing_func=None): if tracing_func is not None and frame_eval_func is not None: # There is no need to set tracing function if frame evaluation is available frame_eval_func() tracing_func = dummy_tracing_func if TracingFunctionHolder._original_tracing is None: #This may happen before replace_sys_set_trace_func is called. sys.settrace(tracing_func) return current_thread = threading.currentThread() do_not_trace_before = getattr(current_thread, 'pydev_do_not_trace', None) if do_not_trace_before: return try: TracingFunctionHolder._lock.acquire() current_thread.pydev_do_not_trace = True # avoid settrace reentering TracingFunctionHolder._warn = False _internal_set_trace(tracing_func) TracingFunctionHolder._warn = True finally: TracingFunctionHolder._lock.release() current_thread.pydev_do_not_trace = do_not_trace_before
def find_frame(thread_id, frame_id): """ returns a frame on the thread that has a given frame_id """ try: curr_thread_id = get_thread_id(threading.currentThread()) if thread_id != curr_thread_id: try: return get_custom_frame(thread_id, frame_id) # I.e.: thread_id could be a stackless frame id + thread_id. except: pass raise VariableError("find_frame: must execute on same thread (%s != %s)" % (thread_id, curr_thread_id)) lookingFor = int(frame_id) if AdditionalFramesContainer.additional_frames: if dict_contains(AdditionalFramesContainer.additional_frames, thread_id): frame = AdditionalFramesContainer.additional_frames[thread_id].get(lookingFor) if frame is not None: return frame curFrame = get_frame() if frame_id == "*": return curFrame # any frame is specified with "*" frameFound = None for frame in _iter_frames(curFrame): if lookingFor == id(frame): frameFound = frame del frame break del frame # Important: python can hold a reference to the frame from the current context # if an exception is raised, so, if we don't explicitly add those deletes # we might have those variables living much more than we'd want to. # I.e.: sys.exc_info holding reference to frame that raises exception (so, other places # need to call sys.exc_clear()) del curFrame if frameFound is None: msgFrames = '' i = 0 for frame in _iter_frames(get_frame()): i += 1 msgFrames += str(id(frame)) if i % 5 == 0: msgFrames += '\n' else: msgFrames += ' - ' errMsg = '''find_frame: frame not found. Looking for thread_id:%s, frame_id:%s Current thread_id:%s, available frames: %s\n ''' % (thread_id, lookingFor, curr_thread_id, msgFrames) sys.stderr.write(errMsg) return None return frameFound except: import traceback traceback.print_exc() return None
def getVariable(thread_id, frame_id, scope, attrs): """ returns the value of a variable :scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME BY_ID means we'll traverse the list of all objects alive to get the object. :attrs: after reaching the proper scope, we have to get the attributes until we find the proper location (i.e.: obj\tattr1\tattr2) :note: when BY_ID is used, the frame_id is considered the id of the object to find and not the frame (as we don't care about the frame in this case). """ if scope == 'BY_ID': if thread_id != get_thread_id(threading.currentThread()): raise VariableError("getVariable: must execute on same thread") try: import gc objects = gc.get_objects() except: pass # Not all python variants have it. else: frame_id = int(frame_id) for var in objects: if id(var) == frame_id: if attrs is not None: attrList = attrs.split('\t') for k in attrList: _type, _typeName, resolver = get_type(var) var = resolver.resolve(var, k) return var # If it didn't return previously, we coudn't find it by id (i.e.: alrceady garbage collected). sys.stderr.write('Unable to find object with id: %s\n' % (frame_id,)) return None frame = find_frame(thread_id, frame_id) if frame is None: return {} if attrs is not None: attrList = attrs.split('\t') else: attrList = [] for attr in attrList: attr.replace("@_@TAB_CHAR@_@", '\t') if scope == 'EXPRESSION': for count in xrange(len(attrList)): if count == 0: # An Expression can be in any scope (globals/locals), therefore it needs to evaluated as an expression var = evaluate_expression(thread_id, frame_id, attrList[count], False) else: _type, _typeName, resolver = get_type(var) var = resolver.resolve(var, attrList[count]) else: if scope == "GLOBAL": var = frame.f_globals del attrList[0] # globals are special, and they get a single dummy unused attribute else: # in a frame access both locals and globals as Python does var = {} var.update(frame.f_globals) var.update(frame.f_locals) for k in attrList: _type, _typeName, resolver = get_type(var) var = resolver.resolve(var, k) return var
def find_frame(thread_id, frame_id): """ returns a frame on the thread that has a given frame_id """ try: curr_thread_id = get_thread_id(threading.currentThread()) if thread_id != curr_thread_id: try: return get_custom_frame(thread_id, frame_id) # I.e.: thread_id could be a stackless frame id + thread_id. except: pass raise VariableError("find_frame: must execute on same thread (%s != %s)" % (thread_id, curr_thread_id)) lookingFor = int(frame_id) if AdditionalFramesContainer.additional_frames: if dict_contains(AdditionalFramesContainer.additional_frames, thread_id): frame = AdditionalFramesContainer.additional_frames[thread_id].get(lookingFor) if frame is not None: return frame curFrame = get_frame() if frame_id == "*": return curFrame # any frame is specified with "*" frameFound = None for frame in _iter_frames(curFrame): if lookingFor == id(frame): frameFound = frame del frame break del frame # Important: python can hold a reference to the frame from the current context # if an exception is raised, so, if we don't explicitly add those deletes # we might have those variables living much more than we'd want to. # I.e.: sys.exc_info holding reference to frame that raises exception (so, other places # need to call sys.exc_clear()) del curFrame if frameFound is None: msgFrames = '' i = 0 for frame in _iter_frames(get_frame()): i += 1 msgFrames += str(id(frame)) if i % 5 == 0: msgFrames += '\n' else: msgFrames += ' - ' errMsg = '''find_frame: frame not found. Looking for thread_id:%s, frame_id:%s Current thread_id:%s, available frames: %s\n ''' % (thread_id, lookingFor, curr_thread_id, msgFrames) sys.stderr.write(errMsg) return None return frameFound except: import traceback traceback.print_exc() return None
def getVariable(thread_id, frame_id, scope, attrs): """ returns the value of a variable :scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME BY_ID means we'll traverse the list of all objects alive to get the object. :attrs: after reaching the proper scope, we have to get the attributes until we find the proper location (i.e.: obj\tattr1\tattr2) :note: when BY_ID is used, the frame_id is considered the id of the object to find and not the frame (as we don't care about the frame in this case). """ if scope == 'BY_ID': if thread_id != get_thread_id(threading.currentThread()): raise VariableError("getVariable: must execute on same thread") try: import gc objects = gc.get_objects() except: pass # Not all python variants have it. else: frame_id = int(frame_id) for var in objects: if id(var) == frame_id: if attrs is not None: attrList = attrs.split('\t') for k in attrList: _type, _typeName, resolver = get_type(var) var = resolver.resolve(var, k) return var # If it didn't return previously, we coudn't find it by id (i.e.: alrceady garbage collected). sys.stderr.write('Unable to find object with id: %s\n' % (frame_id,)) return None frame = find_frame(thread_id, frame_id) if frame is None: return {} if attrs is not None: attrList = attrs.split('\t') else: attrList = [] for attr in attrList: attr.replace("@_@TAB_CHAR@_@", '\t') if scope == 'EXPRESSION': for count in xrange(len(attrList)): if count == 0: # An Expression can be in any scope (globals/locals), therefore it needs to evaluated as an expression var = evaluate_expression(thread_id, frame_id, attrList[count], False) else: _type, _typeName, resolver = get_type(var) var = resolver.resolve(var, attrList[count]) else: if scope == "GLOBAL": var = frame.f_globals del attrList[0] # globals are special, and they get a single dummy unused attribute else: # in a frame access both locals and globals as Python does var = {} var.update(frame.f_globals) var.update(frame.f_locals) for k in attrList: _type, _typeName, resolver = get_type(var) var = resolver.resolve(var, k) return var
is_module = setup['module'] from _pydev_bundle import pydev_localhost if int(port) == 0 and int(client_port) == 0: (h, p) = pydev_localhost.get_socket_name() client_port = p host = pydev_localhost.get_localhost() #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = skip_successful_exit connect_status_queue = _queue.Queue() interpreter = InterpreterInterface(host, int(client_port), threading.currentThread(), connect_status_queue=connect_status_queue) server_thread = threading.Thread(target=start_console_server, name='ServerThread', args=(host, int(port), interpreter)) server_thread.setDaemon(True) server_thread.start() sys.stdin = StdIn(interpreter, host, client_port, sys.stdin) init_mpl_in_console(interpreter) try: success = connect_status_queue.get(True, 60) if not success: raise ValueError()
from _pydev_bundle import pydev_localhost if int(port) == 0 and int(client_port) == 0: (h, p) = pydev_localhost.get_socket_name() client_port = p host = pydev_localhost.get_localhost() #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit interpreter = InterpreterInterface(host, int(client_port), threading.currentThread()) server_thread = threading.Thread(target=start_console_server, name='ServerThread', args=(host, int(port), interpreter)) server_thread.setDaemon(True) server_thread.start() sys.stdin = StdIn(interpreter, host, client_port, sys.stdin) init_mpl_in_console(interpreter) globals = run_file(file, None, None) interpreter.get_namespace().update(globals)
del sys.argv[0] from _pydev_bundle import pydev_localhost if int(port) == 0 and int(client_port) == 0: (h, p) = pydev_localhost.get_socket_name() client_port = p host = pydev_localhost.get_localhost() #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit interpreter = InterpreterInterface(host, int(client_port), threading.currentThread()) server_thread = threading.Thread(target=start_console_server, name='ServerThread', args=(host, int(port), interpreter)) server_thread.setDaemon(True) server_thread.start() sys.stdin = StdIn(interpreter, host, client_port, sys.stdin) globals = run_file(file, None, None) interpreter.get_namespace().update(globals) process_exec_queue(interpreter)
del sys.argv[0] from _pydev_bundle import pydev_localhost if int(port) == 0 and int(client_port) == 0: (h, p) = pydev_localhost.get_socket_name() client_port = p host = pydev_localhost.get_localhost() # replace exit (see comments on method) # note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit interpreter = InterpreterInterface(host, int(client_port), threading.currentThread()) server_thread = threading.Thread( target=start_console_server, name="ServerThread", args=(host, int(port), interpreter) ) server_thread.setDaemon(True) server_thread.start() sys.stdin = StdIn(interpreter, host, client_port, sys.stdin) init_mpl_in_console(interpreter) globals = run_file(file, None, None) interpreter.get_namespace().update(globals)