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 _excepthook(exctype, value, tb):
    from _pydevd_bundle.pydevd_frame import handle_breakpoint_condition, handle_breakpoint_expression
    global _handle_exceptions
    if _handle_exceptions:
        exception_breakpoint = get_exception_breakpoint(exctype, _handle_exceptions)
    else:
        exception_breakpoint = None

    #Always call the original excepthook before going on to call the debugger post mortem to show it.
    _original_excepthook(exctype, value, tb)

    if not exception_breakpoint:
        return

    if tb is None:  #sometimes it can be None, e.g. with GTK
        return

    if exctype is KeyboardInterrupt:
        return

    frames = []
    debugger = get_global_debugger()
    user_frame = None

    while tb:
        frame = tb.tb_frame
        if exception_breakpoint.ignore_libraries and not debugger.not_in_scope(frame.f_code.co_filename):
            user_frame = tb.tb_frame
        frames.append(tb.tb_frame)
        tb = tb.tb_next

    thread = threadingCurrentThread()
    frames_byid = dict([(id(frame),frame) for frame in frames])
    if exception_breakpoint.ignore_libraries and user_frame is not None:
        frame = user_frame
    else:
        frame = frames[-1]
    exception = (exctype, value, tb)
    _set_additional_info_if_needed(thread)

    info = thread.additional_info
    add_exception_to_frame(frame, exception)
    if exception_breakpoint.condition is not None:
        eval_result = handle_breakpoint_condition(debugger, info, exception_breakpoint, frame)
        if not eval_result:
            return

    if exception_breakpoint.expression is not None:
        handle_breakpoint_expression(exception_breakpoint, info, frame)

    try:
        thread.additional_info.pydev_message = exception_breakpoint.qname
    except:
        thread.additional_info.pydev_message = exception_breakpoint.qname.encode('utf-8')

    pydevd_tracing.SetTrace(None) #no tracing from here

    pydev_log.debug('Handling post-mortem stop on exception breakpoint %s' % exception_breakpoint.qname)

    debugger.handle_post_mortem_stop(thread, frame, frames_byid, exception)
Exemple #3
0
 def set_show_return_values(self, py_db, show_return_values):
     if show_return_values:
         py_db.show_return_values = True
     else:
         if py_db.show_return_values:
             # We should remove saved return values
             py_db.remove_return_values_flag = True
         py_db.show_return_values = False
     pydev_log.debug("Show return values: %s\n" % py_db.show_return_values)
Exemple #4
0
def _get_stepping_filters(filters_cache=[]):
    if not filters_cache:
        filters = os.getenv('PYDEVD_FILTERS', '').split(';')
        pydev_log.debug("PYDEVD_FILTERS %s\n" % filters)
        new_filters = []
        for new_filter in filters:
            new_filters.append(new_filter)
        filters_cache.append(new_filters)
    return filters_cache[-1]
Exemple #5
0
def _get_library_roots(library_roots_cache=[]):
    # Note: the project_roots_cache is the same instance among the many calls to the method
    if not library_roots_cache:
        roots = os.getenv('LIBRARY_ROOTS', '').split(os.pathsep)
        pydev_log.debug("LIBRARY_ROOTS %s\n" % roots)
        new_roots = []
        for root in roots:
            new_roots.append(os.path.normcase(root))
        library_roots_cache.append(new_roots)
    return library_roots_cache[-1] # returns the project roots with case normalized
Exemple #6
0
def stop_on_unhandled_exception(py_db, thread, additional_info, arg):
    exctype, value, tb = arg
    break_on_uncaught_exceptions = py_db.break_on_uncaught_exceptions
    if break_on_uncaught_exceptions:
        exception_breakpoint = py_db.get_exception_breakpoint(exctype, break_on_uncaught_exceptions)
    else:
        exception_breakpoint = None

    if not exception_breakpoint:
        return

    if tb is None:  # sometimes it can be None, e.g. with GTK
        return

    if exctype is KeyboardInterrupt:
        return

    if py_db.exclude_exception_by_filter(exception_breakpoint, tb, True):
        return

    frames = []
    user_frame = None

    while tb:
        frame = tb.tb_frame
        if exception_breakpoint.ignore_libraries and py_db.in_project_scope(frame.f_code.co_filename):
            user_frame = tb.tb_frame
        frames.append(tb.tb_frame)
        tb = tb.tb_next

    frames_byid = dict([(id(frame), frame) for frame in frames])
    if exception_breakpoint.ignore_libraries and user_frame is not None:
        frame = user_frame
    else:
        frame = frames[-1]
    add_exception_to_frame(frame, arg)
    if exception_breakpoint.condition is not None:
        eval_result = py_db.handle_breakpoint_condition(additional_info, exception_breakpoint, frame)
        if not eval_result:
            return

    if exception_breakpoint.expression is not None:
        py_db.handle_breakpoint_expression(exception_breakpoint, additional_info, frame)

    try:
        additional_info.pydev_message = exception_breakpoint.qname
    except:
        additional_info.pydev_message = exception_breakpoint.qname.encode('utf-8')

    pydev_log.debug('Handling post-mortem stop on exception breakpoint %s' % (exception_breakpoint.qname,))

    py_db.do_stop_on_unhandled_exception(thread, frame, frames_byid, arg)
Exemple #7
0
    def remove_python_exception_breakpoint(self, py_db, exception):
        try:
            cp = py_db.break_on_uncaught_exceptions.copy()
            cp.pop(exception, None)
            py_db.break_on_uncaught_exceptions = cp

            cp = py_db.break_on_caught_exceptions.copy()
            cp.pop(exception, None)
            py_db.break_on_caught_exceptions = cp
        except:
            pydev_log.debug("Error while removing exception %s" % sys.exc_info()[0])

        py_db.on_breakpoints_changed(removed=True)
Exemple #8
0
def is_ignored_by_filter(filename, filename_to_ignored_by_filters_cache={}):
    try:
        return filename_to_ignored_by_filters_cache[filename]
    except:
        import fnmatch
        for stepping_filter in _get_stepping_filters():
            if fnmatch.fnmatch(filename, stepping_filter):
                pydev_log.debug("File %s ignored by filter %s" % (filename, stepping_filter))
                filename_to_ignored_by_filters_cache[filename] = True
                break
        else:
            filename_to_ignored_by_filters_cache[filename] = False

        return filename_to_ignored_by_filters_cache[filename]
Exemple #9
0
    def should_stop_on_exception(self, frame, event, arg):
        # ENDIF

        # main_debugger, _filename, info, _thread = self._args
        main_debugger = self._args[0]
        info = self._args[2]
        flag = False

        if info.pydev_state != STATE_SUSPEND:  # and breakpoint is not None:
            exception, value, trace = arg

            if trace is not None:  # on jython trace is None on the first event
                exception_breakpoint = get_exception_breakpoint(exception, main_debugger.break_on_caught_exceptions)

                if exception_breakpoint is not None:
                    if exception_breakpoint.ignore_libraries:
                        if exception_breakpoint.notify_on_first_raise_only:
                            if main_debugger.first_appearance_in_scope(trace):
                                add_exception_to_frame(frame, (exception, value, trace))
                                try:
                                    info.pydev_message = exception_breakpoint.qname
                                except:
                                    info.pydev_message = exception_breakpoint.qname.encode("utf-8")
                                flag = True
                            else:
                                pydev_log.debug(
                                    "Ignore exception %s in library %s" % (exception, frame.f_code.co_filename)
                                )
                                flag = False
                    else:
                        if not exception_breakpoint.notify_on_first_raise_only or just_raised(trace):
                            add_exception_to_frame(frame, (exception, value, trace))
                            try:
                                info.pydev_message = exception_breakpoint.qname
                            except:
                                info.pydev_message = exception_breakpoint.qname.encode("utf-8")
                            flag = True
                        else:
                            flag = False
                else:
                    try:
                        if main_debugger.plugin is not None:
                            result = main_debugger.plugin.exception_break(main_debugger, self, frame, self._args, arg)
                            if result:
                                (flag, frame) = result
                    except:
                        flag = False

        return flag, frame
Exemple #10
0
 def exclude_by_filter(self, filename, module_name):
     '''
     :return: True if it should be excluded, False if it should be included and None
         if no rule matched the given file.
     '''
     for exclude_filter in self._exclude_filters:  # : :type exclude_filter: ExcludeFilter
         if exclude_filter.is_path:
             if glob_matches_path(filename, exclude_filter.name):
                 if exclude_filter.exclude:
                     pydev_log.debug("File %s ignored by filter %s" % (filename, exclude_filter.name))
                 return exclude_filter.exclude
         else:
             # Module filter.
             if exclude_filter.name == module_name or module_name.startswith(exclude_filter.name + '.'):
                 return exclude_filter.exclude
     return None
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
Exemple #12
0
    def __init__(self):
        self._exclude_filters = []
        self._project_roots = []
        self._library_roots = []

        # Filter out libraries?
        self._use_libraries_filter = False
        self.require_module = False  # True if some exclude filter filters by the module.

        self.set_use_libraries_filter(os.getenv('PYDEVD_FILTER_LIBRARIES') is not None)

        project_roots = os.getenv('IDE_PROJECT_ROOTS', None)
        if project_roots is not None:
            project_roots = project_roots.split(os.pathsep)
        else:
            project_roots = []
        self.set_project_roots(project_roots)

        library_roots = os.getenv('LIBRARY_ROOTS', None)
        if library_roots is not None:
            library_roots = library_roots.split(os.pathsep)
        else:
            library_roots = self._get_default_library_roots()
        self.set_library_roots(library_roots)

        # Stepping filters.
        pydevd_filters = os.getenv('PYDEVD_FILTERS', '')
        if pydevd_filters.startswith('{'):
            # dict(glob_pattern (str) -> exclude(True or False))
            exclude_filters = []
            for key, val in json.loads(pydevd_filters).items():
                exclude_filters.append(ExcludeFilter(key, val, True))
            self._exclude_filters = exclude_filters
        else:
            # A ';' separated list of strings with globs for the
            # list of excludes.
            filters = pydevd_filters.split(';')
            pydev_log.debug("PYDEVD_FILTERS %s\n" % filters)
            new_filters = []
            for new_filter in filters:
                if new_filter.strip():
                    new_filters.append(ExcludeFilter(new_filter.strip(), True, True))
            self._exclude_filters = new_filters
Exemple #13
0
def _get_source_django_18_or_lower(frame):
    # This method is usable only for the Django <= 1.8
    try:
        node = frame.f_locals['self']
        if hasattr(node, 'source'):
            return node.source
        else:
            if IS_DJANGO18:
                # The debug setting was changed since Django 1.8
                pydev_log.error_once("WARNING: Template path is not available. Set the 'debug' option in the OPTIONS of a DjangoTemplates "
                                     "backend.")
            else:
                # The debug setting for Django < 1.8
                pydev_log.error_once("WARNING: Template path is not available. Please set TEMPLATE_DEBUG=True in your settings.py to make "
                                     "django template breakpoints working")
            return None

    except:
        pydev_log.debug(traceback.format_exc())
        return None
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
Exemple #15
0
def _get_template_file_name(frame):
    try:
        if IS_DJANGO19_OR_HIGHER:
            # The Node source was removed since Django 1.9
            if dict_contains(frame.f_locals, 'context'):
                context = frame.f_locals['context']
                if hasattr(context, 'template') and hasattr(context.template, 'origin') and \
                        hasattr(context.template.origin, 'name'):
                    return context.template.origin.name
            return None

        source = _get_source_django_18_or_lower(frame)
        if source is None:
            pydev_log.debug("Source is None\n")
            return None
        fname = source[0].name

        if fname == '<unknown source>':
            pydev_log.debug("Source name is %s\n" % fname)
            return None
        else:
            abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_file(fname)
            return abs_path_real_path_and_base[1]
    except:
        pydev_log.debug(traceback.format_exc())
        return None
Exemple #16
0
def _get_template_file_name(frame):
    try:
        if IS_DJANGO19:
            # The Node source was removed since Django 1.9
            if 'context' in frame.f_locals:
                context = frame.f_locals['context']
                if hasattr(context, '_has_included_template'):
                    #  if there was included template we need to inspect the previous frames and find its name
                    back = frame.f_back
                    while back is not None and frame.f_code.co_name in ('render', '_render'):
                        locals = back.f_locals
                        if 'self' in locals:
                            self = locals['self']
                            if self.__class__.__name__ == 'Template' and hasattr(self, 'origin') and \
                                    hasattr(self.origin, 'name'):
                                return normcase(self.origin.name)
                        back = back.f_back
                else:
                    if hasattr(context, 'template') and hasattr(context.template, 'origin') and \
                            hasattr(context.template.origin, 'name'):
                        return normcase(context.template.origin.name)
            return None
        elif IS_DJANGO19_OR_HIGHER:
            # For Django 1.10 and later there is much simpler way to get template name
            if 'self' in frame.f_locals:
                self = frame.f_locals['self']
                if hasattr(self, 'origin') and hasattr(self.origin, 'name'):
                    return normcase(self.origin.name)
            return None

        source = _get_source_django_18_or_lower(frame)
        if source is None:
            pydev_log.debug("Source is None\n")
            return None
        fname = source[0].name

        if fname == '<unknown source>':
            pydev_log.debug("Source name is %s\n" % fname)
            return None
        else:
            abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_file(fname)
            return abs_path_real_path_and_base[1]
    except:
        pydev_log.debug(traceback.format_exc())
        return None
Exemple #17
0
def get_breakpoint(plugin, main_debugger, pydb_frame, frame, event, args):
    main_debugger, filename, info, thread = args
    flag = False
    django_breakpoint = None
    new_frame = None
    type = 'django'

    if event == 'call' and info.pydev_state != STATE_SUSPEND and \
            main_debugger.django_breakpoints and _is_django_render_call(frame):
        filename = _get_template_file_name(frame)
        pydev_log.debug("Django is rendering a template: %s\n" % filename)
        django_breakpoints_for_file = main_debugger.django_breakpoints.get(filename)
        if django_breakpoints_for_file:
            pydev_log.debug("Breakpoints for that file: %s\n" % django_breakpoints_for_file)
            template_line = _get_template_line(frame)
            pydev_log.debug("Tracing template line: %d\n" % template_line)

            if dict_contains(django_breakpoints_for_file, template_line):
                django_breakpoint = django_breakpoints_for_file[template_line]
                flag = True
                new_frame = DjangoTemplateFrame(frame)
    return flag, django_breakpoint, new_frame, type
Exemple #18
0
def set_library_roots(roots):
    roots = _set_roots(roots, _LIBRARY_ROOTS_CACHE)
    pydev_log.debug("LIBRARY_ROOTS %s\n" % roots)
 def set_use_libraries_filter(self, use):
     pydev_log.debug("pydevd: Use libraries filter: %s\n" % use)
     self._use_libraries_filter = use
Exemple #20
0
    def _on_run(self):
        try:
            content_len = -1

            while not self.killReceived:
                try:
                    line = self._read_line()

                    if len(line) == 0:
                        self.handle_except()
                        return  # Finished communication.

                    if line.startswith(b'Content-Length:'):
                        content_len = int(line.strip().split(b':', 1)[1])
                        continue

                    if content_len != -1:
                        # If we previously received a content length, read until a '\r\n'.
                        if line == b'\r\n':
                            json_contents = self._read(content_len)
                            content_len = -1

                            if len(json_contents) == 0:
                                self.handle_except()
                                return  # Finished communication.

                            # We just received a json message, let's process it.
                            self.process_net_command_json(
                                self.global_debugger_holder.global_dbg,
                                json_contents)

                        continue
                    else:
                        # No content len, regular line-based protocol message (remove trailing new-line).
                        if line.endswith(b'\n\n'):
                            line = line[:-2]

                        elif line.endswith(b'\n'):
                            line = line[:-1]

                        elif line.endswith(b'\r'):
                            line = line[:-1]
                except:
                    if not self.killReceived:
                        traceback.print_exc()
                        self.handle_except()
                    return  # Finished communication.

                # Note: the java backend is always expected to pass utf-8 encoded strings. We now work with unicode
                # internally and thus, we may need to convert to the actual encoding where needed (i.e.: filenames
                # on python 2 may need to be converted to the filesystem encoding).
                if hasattr(line, 'decode'):
                    line = line.decode('utf-8')

                if DebugInfoHolder.DEBUG_RECORD_SOCKET_READS:
                    sys.stderr.write(u'debugger: received >>%s<<\n' % (line, ))
                    sys.stderr.flush()

                args = line.split(u'\t', 2)
                try:
                    cmd_id = int(args[0])
                    pydev_log.debug('Received command: %s %s\n' % (
                        ID_TO_MEANING.get(str(cmd_id), '???'),
                        line,
                    ))
                    self.process_command(cmd_id, int(args[1]), args[2])
                except:
                    if traceback is not None and sys is not None:  # Could happen at interpreter shutdown
                        traceback.print_exc()
                        sys.stderr.write("Can't process net command: %s\n" %
                                         line)
                        sys.stderr.flush()

        except:
            if not self.killReceived:
                if traceback is not None:  # Could happen at interpreter shutdown
                    traceback.print_exc()
            self.handle_except()
Exemple #21
0
    def add_breakpoint(self, py_db, filename, breakpoint_type, breakpoint_id,
                       line, condition, func_name, expression, suspend_policy,
                       hit_condition, is_logpoint):
        '''
        :param str filename:
            Note: must be already translated for the server.

        :param str breakpoint_type:
            One of: 'python-line', 'django-line', 'jinja2-line'.

        :param int breakpoint_id:

        :param int line:

        :param condition:
            Either None or the condition to activate the breakpoint.

        :param str func_name:
            If "None" (str), may hit in any context.
            Empty string will hit only top level.
            Any other value must match the scope of the method to be matched.

        :param str expression:
            None or the expression to be evaluated.

        :param suspend_policy:
            Either "NONE" (to suspend only the current thread when the breakpoint is hit) or
            "ALL" (to suspend all threads when a breakpoint is hit).

        :param str hit_condition:
            An expression where `@HIT@` will be replaced by the number of hits.
            i.e.: `@HIT@ == x` or `@HIT@ >= x`

        :param bool is_logpoint:
            If True and an expression is passed, pydevd will create an io message command with the
            result of the evaluation.

        :return int:
            :see: ADD_BREAKPOINT_NO_ERROR = 0
            :see: ADD_BREAKPOINT_FILE_NOT_FOUND = 1
            :see: ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS = 2
        '''
        assert filename.__class__ == str  # i.e.: bytes on py2 and str on py3
        assert func_name.__class__ == str  # i.e.: bytes on py2 and str on py3

        if not pydevd_file_utils.exists(filename):
            return self.ADD_BREAKPOINT_FILE_NOT_FOUND

        error_code = self.ADD_BREAKPOINT_NO_ERROR
        if (py_db.is_files_filter_enabled
                and not py_db.get_require_module_for_filters()
                and py_db.apply_files_filter(self._DummyFrame(filename),
                                             filename, False)):
            # Note that if `get_require_module_for_filters()` returns False, we don't do this check.
            # This is because we don't have the module name given a file at this point (in
            # runtime it's gotten from the frame.f_globals).
            # An option could be calculate it based on the filename and current sys.path,
            # but on some occasions that may be wrong (for instance with `__main__` or if
            # the user dynamically changes the PYTHONPATH).

            # Note: depending on the use-case, filters may be changed, so, keep on going and add the
            # breakpoint even with the error code.
            error_code = self.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS

        if breakpoint_type == 'python-line':
            added_breakpoint = LineBreakpoint(line,
                                              condition,
                                              func_name,
                                              expression,
                                              suspend_policy,
                                              hit_condition=hit_condition,
                                              is_logpoint=is_logpoint)
            breakpoints = py_db.breakpoints
            file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
            supported_type = True

        else:
            result = None
            plugin = py_db.get_plugin_lazy_init()
            if plugin is not None:
                result = plugin.add_breakpoint('add_line_breakpoint',
                                               py_db,
                                               breakpoint_type,
                                               filename,
                                               line,
                                               condition,
                                               expression,
                                               func_name,
                                               hit_condition=hit_condition,
                                               is_logpoint=is_logpoint)
            if result is not None:
                supported_type = True
                added_breakpoint, breakpoints = result
                file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
            else:
                supported_type = False

        if not supported_type:
            raise NameError(breakpoint_type)

        if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
            pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n',
                            filename, line, func_name)

        if filename in file_to_id_to_breakpoint:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename]
        else:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename] = {}

        id_to_pybreakpoint[breakpoint_id] = added_breakpoint
        py_db.consolidate_breakpoints(filename, id_to_pybreakpoint,
                                      breakpoints)
        if py_db.plugin is not None:
            py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

        py_db.on_breakpoints_changed()
        return error_code
 def set_project_roots(self, project_roots):
     self._project_roots = self._fix_roots(project_roots)
     pydev_log.debug("IDE_PROJECT_ROOTS %s\n" % project_roots)
Exemple #23
0
    def add_breakpoint(self, py_db, filename, breakpoint_type, breakpoint_id,
                       line, condition, func_name, expression, suspend_policy,
                       hit_condition, is_logpoint):
        '''
        :param str filename:
            Note: must be already translated for the server.

        :param str breakpoint_type:
            One of: 'python-line', 'django-line', 'jinja2-line'.

        :param int breakpoint_id:

        :param int line:

        :param condition:
            Either None or the condition to activate the breakpoint.

        :param str func_name:
            If "None" (str), may hit in any context.
            Empty string will hit only top level.
            Any other value must match the scope of the method to be matched.

        :param str expression:
            None or the expression to be evaluated.

        :param suspend_policy:
            Either "NONE" (to suspend only the current thread when the breakpoint is hit) or
            "ALL" (to suspend all threads when a breakpoint is hit).

        :param str hit_condition:
            An expression where `@HIT@` will be replaced by the number of hits.
            i.e.: `@HIT@ == x` or `@HIT@ >= x`

        :param bool is_logpoint:
            If True and an expression is passed, pydevd will create an io message command with the
            result of the evaluation.
        '''
        assert filename.__class__ == str  # i.e.: bytes on py2 and str on py3
        assert func_name.__class__ == str  # i.e.: bytes on py2 and str on py3

        if not pydevd_file_utils.exists(filename):
            sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\
                ' to file that does not exist: %s (will have no effect)\n' % (filename,))
            sys.stderr.flush()
            return

        if breakpoint_type == 'python-line':
            added_breakpoint = LineBreakpoint(line,
                                              condition,
                                              func_name,
                                              expression,
                                              suspend_policy,
                                              hit_condition=hit_condition,
                                              is_logpoint=is_logpoint)
            breakpoints = py_db.breakpoints
            file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
            supported_type = True

        else:
            result = None
            plugin = py_db.get_plugin_lazy_init()
            if plugin is not None:
                result = plugin.add_breakpoint('add_line_breakpoint',
                                               py_db,
                                               breakpoint_type,
                                               filename,
                                               line,
                                               condition,
                                               expression,
                                               func_name,
                                               hit_condition=hit_condition,
                                               is_logpoint=is_logpoint)
            if result is not None:
                supported_type = True
                added_breakpoint, breakpoints = result
                file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
            else:
                supported_type = False

        if not supported_type:
            raise NameError(breakpoint_type)

        if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
            pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n' %
                            (filename, line, func_name))
            sys.stderr.flush()

        if filename in file_to_id_to_breakpoint:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename]
        else:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename] = {}

        id_to_pybreakpoint[breakpoint_id] = added_breakpoint
        py_db.consolidate_breakpoints(filename, id_to_pybreakpoint,
                                      breakpoints)
        if py_db.plugin is not None:
            py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

        py_db.on_breakpoints_changed()
Exemple #24
0
def is_filter_libraries():
    is_filter = os.getenv('PYDEVD_FILTER_LIBRARIES') is not None
    pydev_log.debug("PYDEVD_FILTER_LIBRARIES %s\n" % is_filter)
    return is_filter
def _internal_patch_qt(QtCore, qt_support_mode='auto'):
    pydev_log.debug('Patching Qt: %s', QtCore)

    _original_thread_init = QtCore.QThread.__init__
    _original_runnable_init = QtCore.QRunnable.__init__
    _original_QThread = QtCore.QThread

    class FuncWrapper:

        def __init__(self, original):
            self._original = original

        def __call__(self, *args, **kwargs):
            set_trace_in_qt()
            return self._original(*args, **kwargs)

    class StartedSignalWrapper(QtCore.QObject):  # Wrapper for the QThread.started signal

        try:
            _signal = QtCore.Signal()  # @UndefinedVariable
        except:
            _signal = QtCore.pyqtSignal()  # @UndefinedVariable

        def __init__(self, thread, original_started):
            QtCore.QObject.__init__(self)
            self.thread = thread
            self.original_started = original_started
            if qt_support_mode in ('pyside', 'pyside2'):
                self._signal = original_started
            else:
                self._signal.connect(self._on_call)
                self.original_started.connect(self._signal)

        def connect(self, func, *args, **kwargs):
            if qt_support_mode in ('pyside', 'pyside2'):
                return self._signal.connect(FuncWrapper(func), *args, **kwargs)
            else:
                return self._signal.connect(func, *args, **kwargs)

        def disconnect(self, *args, **kwargs):
            return self._signal.disconnect(*args, **kwargs)

        def emit(self, *args, **kwargs):
            return self._signal.emit(*args, **kwargs)

        def _on_call(self, *args, **kwargs):
            set_trace_in_qt()

    class ThreadWrapper(QtCore.QThread):  # Wrapper for QThread

        def __init__(self, *args, **kwargs):
            _original_thread_init(self, *args, **kwargs)

            # In PyQt5 the program hangs when we try to call original run method of QThread class.
            # So we need to distinguish instances of QThread class and instances of QThread inheritors.
            if self.__class__.run == _original_QThread.run:
                self.run = self._exec_run
            else:
                self._original_run = self.run
                self.run = self._new_run
            self._original_started = self.started
            self.started = StartedSignalWrapper(self, self.started)

        def _exec_run(self):
            set_trace_in_qt()
            self.exec_()
            return None

        def _new_run(self):
            set_trace_in_qt()
            return self._original_run()

    class RunnableWrapper(QtCore.QRunnable):  # Wrapper for QRunnable

        def __init__(self, *args, **kwargs):
            _original_runnable_init(self, *args, **kwargs)

            self._original_run = self.run
            self.run = self._new_run

        def _new_run(self):
            set_trace_in_qt()
            return self._original_run()

    QtCore.QThread = ThreadWrapper
    QtCore.QRunnable = RunnableWrapper
Exemple #26
0
def patch_args(args, is_exec=False):
    '''
    :param list args:
        Arguments to patch.

    :param bool is_exec:
        If it's an exec, the current process will be replaced (this means we have
        to keep the same ppid).
    '''
    try:
        pydev_log.debug("Patching args: %s", args)
        original_args = args
        unquoted_args = remove_quotes_from_args(args)

        # Internally we should reference original_args (if we want to return them) or unquoted_args
        # to add to the list which will be then quoted in the end.
        del args

        from pydevd import SetupHolder
        if not unquoted_args:
            return original_args

        if not is_python(unquoted_args[0]):
            pydev_log.debug("Process is not python, returning.")
            return original_args

        # Note: we create a copy as string to help with analyzing the arguments, but
        # the final list should have items from the unquoted_args as they were initially.
        args_as_str = _get_str_type_compatible('', unquoted_args)

        params_with_value_in_separate_arg = (
            '--check-hash-based-pycs',
            '--jit'  # pypy option
        )

        # All short switches may be combined together. The ones below require a value and the
        # value itself may be embedded in the arg.
        #
        # i.e.: Python accepts things as:
        #
        # python -OQold -qmtest
        #
        # Which is the same as:
        #
        # python -O -Q old -q -m test
        #
        # or even:
        #
        # python -OQold "-vcimport sys;print(sys)"
        #
        # Which is the same as:
        #
        # python -O -Q old -v -c "import sys;print(sys)"

        params_with_combinable_arg = set(('W', 'X', 'Q', 'c', 'm'))

        module_name = None
        before_module_flag = ''
        module_name_i_start = -1
        module_name_i_end = -1

        code = None
        code_i = -1
        code_i_end = -1
        code_flag = ''

        filename = None
        filename_i = -1

        ignore_next = True  # start ignoring the first (the first entry is the python executable)
        for i, arg_as_str in enumerate(args_as_str):
            if ignore_next:
                ignore_next = False
                continue

            if arg_as_str.startswith('-'):
                if arg_as_str == '-':
                    # Contents will be read from the stdin. This is not currently handled.
                    pydev_log.debug(
                        'Unable to fix arguments to attach debugger on subprocess when reading from stdin ("python ... -").'
                    )
                    return original_args

                if arg_as_str.startswith(params_with_value_in_separate_arg):
                    if arg_as_str in params_with_value_in_separate_arg:
                        ignore_next = True
                    continue

                break_out = False
                for j, c in enumerate(arg_as_str):

                    # i.e.: Python supports -X faulthandler as well as -Xfaulthandler
                    # (in one case we have to ignore the next and in the other we don't
                    # have to ignore it).
                    if c in params_with_combinable_arg:
                        remainder = arg_as_str[j + 1:]
                        if not remainder:
                            ignore_next = True

                        if c == 'm':
                            # i.e.: Something as
                            # python -qm test
                            # python -m test
                            # python -qmtest
                            before_module_flag = arg_as_str[:
                                                            j]  # before_module_flag would then be "-q"
                            if before_module_flag == '-':
                                before_module_flag = ''
                            module_name_i_start = i
                            if not remainder:
                                module_name = unquoted_args[i + 1]
                                module_name_i_end = i + 1
                            else:
                                # i.e.: python -qmtest should provide 'test' as the module_name
                                module_name = unquoted_args[i][j + 1:]
                                module_name_i_end = module_name_i_start
                            break_out = True
                            break

                        elif c == 'c':
                            # i.e.: Something as
                            # python -qc "import sys"
                            # python -c "import sys"
                            # python "-qcimport sys"
                            code_flag = arg_as_str[:j +
                                                   1]  # code_flag would then be "-qc"

                            if not remainder:
                                # arg_as_str is something as "-qc", "import sys"
                                code = unquoted_args[i + 1]
                                code_i_end = i + 2
                            else:
                                # if arg_as_str is something as "-qcimport sys"
                                code = remainder  # code would be "import sys"
                                code_i_end = i + 1
                            code_i = i
                            break_out = True
                            break

                        else:
                            break

                if break_out:
                    break

            else:
                # It doesn't start with '-' and we didn't ignore this entry:
                # this means that this is the file to be executed.
                filename = unquoted_args[i]
                filename_i = i

                # When executing .zip applications, don't attach the debugger.
                extensions = _get_str_type_compatible(
                    filename, ['.zip', '.pyz', '.pyzw'])
                for ext in extensions:
                    if filename.endswith(ext):
                        pydev_log.debug(
                            'Executing a PyZip (debugger will not be attached to subprocess).'
                        )
                        return original_args

                if _is_managed_arg(filename):  # no need to add pydevd twice
                    pydev_log.debug(
                        'Skipped monkey-patching as pydevd.py is in args already.'
                    )
                    return original_args

                break
        else:
            # We didn't find the filename (something is unexpected).
            pydev_log.debug(
                'Unable to fix arguments to attach debugger on subprocess (filename not found).'
            )
            return original_args

        if code_i != -1:
            host, port = _get_host_port()

            if port is not None:
                new_args = []
                new_args.extend(unquoted_args[:code_i])
                new_args.append(code_flag)
                new_args.append(
                    _get_python_c_args(host, port, code, unquoted_args,
                                       SetupHolder.setup))
                new_args.extend(unquoted_args[code_i_end:])

                return quote_args(new_args)

        first_non_vm_index = max(filename_i, module_name_i_start)
        if first_non_vm_index == -1:
            pydev_log.debug(
                'Unable to fix arguments to attach debugger on subprocess (could not resolve filename nor module name).'
            )
            return original_args

        # Original args should be something as:
        # ['X:\\pysrc\\pydevd.py', '--multiprocess', '--print-in-debugger-startup',
        #  '--vm_type', 'python', '--client', '127.0.0.1', '--port', '56352', '--file', 'x:\\snippet1.py']
        from _pydevd_bundle.pydevd_command_line_handling import setup_to_argv
        new_args = []
        new_args.extend(unquoted_args[:first_non_vm_index])
        if before_module_flag:
            new_args.append(before_module_flag)

        add_module_at = len(new_args) + 1

        new_args.extend(
            setup_to_argv(
                _get_setup_updated_with_protocol_and_ppid(SetupHolder.setup,
                                                          is_exec=is_exec)))
        new_args.append('--file')

        if module_name is not None:
            assert module_name_i_start != -1
            assert module_name_i_end != -1
            # Always after 'pydevd' (i.e.: pydevd "--module" --multiprocess ...)
            new_args.insert(add_module_at, '--module')
            new_args.append(module_name)
            new_args.extend(unquoted_args[module_name_i_end + 1:])

        elif filename is not None:
            assert filename_i != -1
            new_args.append(filename)
            new_args.extend(unquoted_args[filename_i + 1:])

        else:
            raise AssertionError('Internal error (unexpected condition)')

        return quote_args(new_args)
    except:
        pydev_log.exception(
            'Error patching args (debugger not attached to subprocess).')
        return original_args
Exemple #27
0
def set_project_roots(project_roots):
    project_roots = _set_roots(project_roots, _PROJECT_ROOTS_CACHE)
    pydev_log.debug("IDE_PROJECT_ROOTS %s\n" % project_roots)
Exemple #28
0
def _excepthook(exctype, value, tb):
    from _pydevd_bundle.pydevd_frame import handle_breakpoint_condition, handle_breakpoint_expression
    global _handle_exceptions
    if _handle_exceptions:
        exception_breakpoint = get_exception_breakpoint(
            exctype, _handle_exceptions)
    else:
        exception_breakpoint = None

    #Always call the original excepthook before going on to call the debugger post mortem to show it.
    _original_excepthook(exctype, value, tb)

    if not exception_breakpoint:
        return

    if tb is None:  #sometimes it can be None, e.g. with GTK
        return

    if exctype is KeyboardInterrupt:
        return

    frames = []
    debugger = get_global_debugger()
    user_frame = None

    while tb:
        frame = tb.tb_frame
        if exception_breakpoint.ignore_libraries and not debugger.not_in_scope(
                frame.f_code.co_filename):
            user_frame = tb.tb_frame
        frames.append(tb.tb_frame)
        tb = tb.tb_next

    thread = threadingCurrentThread()
    frames_byid = dict([(id(frame), frame) for frame in frames])
    if exception_breakpoint.ignore_libraries and user_frame is not None:
        frame = user_frame
    else:
        frame = frames[-1]
    exception = (exctype, value, tb)
    _set_additional_info_if_needed(thread)

    info = thread.additional_info
    add_exception_to_frame(frame, exception)
    if exception_breakpoint.condition is not None:
        eval_result = handle_breakpoint_condition(debugger, info,
                                                  exception_breakpoint, frame)
        if not eval_result:
            return

    if exception_breakpoint.expression is not None:
        handle_breakpoint_expression(exception_breakpoint, info, frame)

    try:
        thread.additional_info.pydev_message = exception_breakpoint.qname
    except:
        thread.additional_info.pydev_message = exception_breakpoint.qname.encode(
            'utf-8')

    thread.additional_info.pydev_message = 'python-%s' % thread.additional_info.pydev_message

    pydevd_tracing.SetTrace(None)  #no tracing from here

    pydev_log.debug('Handling post-mortem stop on exception breakpoint %s' %
                    exception_breakpoint.qname)

    debugger.handle_post_mortem_stop(thread, frame, frames_byid, exception)
Exemple #29
0
def patch_args(args):
    try:
        pydev_log.debug("Patching args: %s", args)
        args = remove_quotes_from_args(args)

        from pydevd import SetupHolder
        new_args = []
        if len(args) == 0:
            return args

        if is_python(args[0]):
            ind_c = get_c_option_index(args)

            if ind_c != -1:
                host, port = _get_host_port()

                if port is not None:
                    new_args.extend(args)
                    new_args[ind_c + 1] = _get_python_c_args(
                        host, port, ind_c, args, SetupHolder.setup)
                    return quote_args(new_args)
            else:
                # Check for Python ZIP Applications and don't patch the args for them.
                # Assumes the first non `-<flag>` argument is what we need to check.
                # There's probably a better way to determine this but it works for most cases.
                continue_next = False
                for i in range(1, len(args)):
                    if continue_next:
                        continue_next = False
                        continue

                    arg = args[i]
                    if arg.startswith('-'):
                        # Skip the next arg too if this flag expects a value.
                        continue_next = arg in ['-m', '-W', '-X']
                        continue

                    if arg.rsplit('.')[-1] in ['zip', 'pyz', 'pyzw']:
                        pydev_log.debug('Executing a PyZip, returning')
                        return args
                    break

                new_args.append(args[0])
        else:
            pydev_log.debug("Process is not python, returning.")
            return args

        i = 1
        # Original args should be something as:
        # ['X:\\pysrc\\pydevd.py', '--multiprocess', '--print-in-debugger-startup',
        #  '--vm_type', 'python', '--client', '127.0.0.1', '--port', '56352', '--file', 'x:\\snippet1.py']
        from _pydevd_bundle.pydevd_command_line_handling import setup_to_argv
        original = setup_to_argv(SetupHolder.setup) + ['--file']
        while i < len(args):
            if args[i] == '-m':
                # Always insert at pos == 1 (i.e.: pydevd "--module" --multiprocess ...)
                original.insert(1, '--module')
            else:
                if args[i].startswith('-'):
                    new_args.append(args[i])
                else:
                    break
            i += 1

        # Note: undoing https://github.com/Elizaveta239/PyDev.Debugger/commit/053c9d6b1b455530bca267e7419a9f63bf51cddf
        # (i >= len(args) instead of i < len(args))
        # in practice it'd raise an exception here and would return original args, which is not what we want... providing
        # a proper fix for https://youtrack.jetbrains.com/issue/PY-9767 elsewhere.
        if i < len(args) and _is_managed_arg(
                args[i]):  # no need to add pydevd twice
            return args

        for x in original:
            new_args.append(x)
            if x == '--file':
                break

        while i < len(args):
            new_args.append(args[i])
            i += 1

        return quote_args(new_args)
    except:
        pydev_log.exception('Error patching args')
        return args
Exemple #30
0
    def add_breakpoint(self,
                       py_db,
                       original_filename,
                       breakpoint_type,
                       breakpoint_id,
                       line,
                       condition,
                       func_name,
                       expression,
                       suspend_policy,
                       hit_condition,
                       is_logpoint,
                       adjust_line=False):
        '''
        :param str original_filename:
            Note: must be sent as it was received in the protocol. It may be translated in this
            function and its final value will be available in the returned _AddBreakpointResult.

        :param str breakpoint_type:
            One of: 'python-line', 'django-line', 'jinja2-line'.

        :param int breakpoint_id:

        :param int line:
            Note: it's possible that a new line was actually used. If that's the case its
            final value will be available in the returned _AddBreakpointResult.

        :param condition:
            Either None or the condition to activate the breakpoint.

        :param str func_name:
            If "None" (str), may hit in any context.
            Empty string will hit only top level.
            Any other value must match the scope of the method to be matched.

        :param str expression:
            None or the expression to be evaluated.

        :param suspend_policy:
            Either "NONE" (to suspend only the current thread when the breakpoint is hit) or
            "ALL" (to suspend all threads when a breakpoint is hit).

        :param str hit_condition:
            An expression where `@HIT@` will be replaced by the number of hits.
            i.e.: `@HIT@ == x` or `@HIT@ >= x`

        :param bool is_logpoint:
            If True and an expression is passed, pydevd will create an io message command with the
            result of the evaluation.

        :return _AddBreakpointResult:
        '''
        assert original_filename.__class__ == str, 'Expected str, found: %s' % (
            original_filename.__class__, )  # i.e.: bytes on py2 and str on py3

        pydev_log.debug('Request for breakpoint in: %s line: %s',
                        original_filename, line)
        # Parameters to reapply breakpoint.
        api_add_breakpoint_params = (original_filename, breakpoint_type,
                                     breakpoint_id, line, condition, func_name,
                                     expression, suspend_policy, hit_condition,
                                     is_logpoint)

        translated_filename = self.filename_to_server(
            original_filename)  # Apply user path mapping.
        pydev_log.debug('Breakpoint (after path translation) in: %s line: %s',
                        translated_filename, line)
        func_name = self.to_str(func_name)

        assert translated_filename.__class__ == str  # i.e.: bytes on py2 and str on py3
        assert func_name.__class__ == str  # i.e.: bytes on py2 and str on py3

        # Apply source mapping (i.e.: ipython).
        source_mapped_filename, new_line, multi_mapping_applied = py_db.source_mapping.map_to_server(
            translated_filename, line)

        if multi_mapping_applied:
            pydev_log.debug(
                'Breakpoint (after source mapping) in: %s line: %s',
                source_mapped_filename, new_line)
            # Note that source mapping is internal and does not change the resulting filename nor line
            # (we want the outside world to see the line in the original file and not in the ipython
            # cell, otherwise the editor wouldn't be correct as the returned line is the line to
            # which the breakpoint will be moved in the editor).
            result = self._AddBreakpointResult(original_filename, line)

            # If a multi-mapping was applied, consider it the canonical / source mapped version (translated to ipython cell).
            translated_absolute_filename = source_mapped_filename
            canonical_normalized_filename = pydevd_file_utils.normcase(
                source_mapped_filename)
            line = new_line

        else:
            translated_absolute_filename = pydevd_file_utils.absolute_path(
                translated_filename)
            canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(
                translated_filename)

            if adjust_line and not translated_absolute_filename.startswith(
                    '<'):
                # Validate breakpoints and adjust their positions.
                try:
                    lines = sorted(
                        _get_code_lines(translated_absolute_filename))
                except Exception:
                    pass
                else:
                    if line not in lines:
                        # Adjust to the first preceding valid line.
                        idx = bisect.bisect_left(lines, line)
                        if idx > 0:
                            line = lines[idx - 1]

            result = self._AddBreakpointResult(original_filename, line)

        py_db.api_received_breakpoints[(original_filename, breakpoint_id)] = (
            canonical_normalized_filename, api_add_breakpoint_params)

        if not translated_absolute_filename.startswith('<'):
            # Note: if a mapping pointed to a file starting with '<', don't validate.

            if not pydevd_file_utils.exists(translated_absolute_filename):
                result.error_code = self.ADD_BREAKPOINT_FILE_NOT_FOUND
                return result

            if (py_db.is_files_filter_enabled
                    and not py_db.get_require_module_for_filters()
                    and py_db.apply_files_filter(
                        self._DummyFrame(translated_absolute_filename),
                        translated_absolute_filename, False)):
                # Note that if `get_require_module_for_filters()` returns False, we don't do this check.
                # This is because we don't have the module name given a file at this point (in
                # runtime it's gotten from the frame.f_globals).
                # An option could be calculate it based on the filename and current sys.path,
                # but on some occasions that may be wrong (for instance with `__main__` or if
                # the user dynamically changes the PYTHONPATH).

                # Note: depending on the use-case, filters may be changed, so, keep on going and add the
                # breakpoint even with the error code.
                result.error_code = self.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS

        if breakpoint_type == 'python-line':
            added_breakpoint = LineBreakpoint(line,
                                              condition,
                                              func_name,
                                              expression,
                                              suspend_policy,
                                              hit_condition=hit_condition,
                                              is_logpoint=is_logpoint)
            breakpoints = py_db.breakpoints
            file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
            supported_type = True

        else:
            add_plugin_breakpoint_result = None
            plugin = py_db.get_plugin_lazy_init()
            if plugin is not None:
                add_plugin_breakpoint_result = plugin.add_breakpoint(
                    'add_line_breakpoint',
                    py_db,
                    breakpoint_type,
                    canonical_normalized_filename,
                    line,
                    condition,
                    expression,
                    func_name,
                    hit_condition=hit_condition,
                    is_logpoint=is_logpoint)

            if add_plugin_breakpoint_result is not None:
                supported_type = True
                added_breakpoint, breakpoints = add_plugin_breakpoint_result
                file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
            else:
                supported_type = False

        if not supported_type:
            raise NameError(breakpoint_type)

        if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
            pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n',
                            canonical_normalized_filename, line, func_name)

        if canonical_normalized_filename in file_to_id_to_breakpoint:
            id_to_pybreakpoint = file_to_id_to_breakpoint[
                canonical_normalized_filename]
        else:
            id_to_pybreakpoint = file_to_id_to_breakpoint[
                canonical_normalized_filename] = {}

        id_to_pybreakpoint[breakpoint_id] = added_breakpoint
        py_db.consolidate_breakpoints(canonical_normalized_filename,
                                      id_to_pybreakpoint, breakpoints)
        if py_db.plugin is not None:
            py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

        py_db.on_breakpoints_changed()
        return result
def patch_qt(qt_support_mode):
    '''
    This method patches qt (PySide2, PySide, PyQt4, PyQt5) so that we have hooks to set the tracing for QThread.
    '''
    if not qt_support_mode:
        return

    if qt_support_mode is True or qt_support_mode == 'True':
        # do not break backward compatibility
        qt_support_mode = 'auto'

    if qt_support_mode == 'auto':
        qt_support_mode = os.getenv('PYDEVD_PYQT_MODE', 'auto')

    # Avoid patching more than once
    global _patched_qt
    if _patched_qt:
        return

    pydev_log.debug('Qt support mode: %s', qt_support_mode)

    _patched_qt = True

    if qt_support_mode == 'auto':

        patch_qt_on_import = None
        try:
            import PySide2  # @UnresolvedImport @UnusedImport
            qt_support_mode = 'pyside2'
        except:
            try:
                import Pyside  # @UnresolvedImport @UnusedImport
                qt_support_mode = 'pyside'
            except:
                try:
                    import PyQt5  # @UnresolvedImport @UnusedImport
                    qt_support_mode = 'pyqt5'
                except:
                    try:
                        import PyQt4  # @UnresolvedImport @UnusedImport
                        qt_support_mode = 'pyqt4'
                    except:
                        return

    if qt_support_mode == 'pyside2':
        try:
            import PySide2.QtCore  # @UnresolvedImport
            _internal_patch_qt(PySide2.QtCore, qt_support_mode)
        except:
            return

    elif qt_support_mode == 'pyside':
        try:
            import PySide.QtCore  # @UnresolvedImport
            _internal_patch_qt(PySide.QtCore, qt_support_mode)
        except:
            return

    elif qt_support_mode == 'pyqt5':
        try:
            import PyQt5.QtCore  # @UnresolvedImport
            _internal_patch_qt(PyQt5.QtCore)
        except:
            return

    elif qt_support_mode == 'pyqt4':
        # Ok, we have an issue here:
        # PyDev-452: Selecting PyQT API version using sip.setapi fails in debug mode
        # http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
        # Mostly, if the user uses a different API version (i.e.: v2 instead of v1),
        # that has to be done before importing PyQt4 modules (PySide/PyQt5 don't have this issue
        # as they only implements v2).
        patch_qt_on_import = 'PyQt4'

        def get_qt_core_module():
            import PyQt4.QtCore  # @UnresolvedImport
            return PyQt4.QtCore

        _patch_import_to_patch_pyqt_on_import(patch_qt_on_import, get_qt_core_module)

    else:
        raise ValueError('Unexpected qt support mode: %s' % (qt_support_mode,))
Exemple #32
0
    def add_breakpoint(
            self, py_db, filename, breakpoint_type, breakpoint_id, line, condition, func_name, expression, suspend_policy, hit_condition, is_logpoint):
        '''
        :param str filename:
            Note: must be already translated for the server.

        :param str breakpoint_type:
            One of: 'python-line', 'django-line', 'jinja2-line'.

        :param int breakpoint_id:

        :param int line:

        :param condition:
            Either None or the condition to activate the breakpoint.

        :param str func_name:
            If "None" (str), may hit in any context.
            Empty string will hit only top level.
            Any other value must match the scope of the method to be matched.

        :param str expression:
            None or the expression to be evaluated.

        :param suspend_policy:
            Either "NONE" (to suspend only the current thread when the breakpoint is hit) or
            "ALL" (to suspend all threads when a breakpoint is hit).

        :param str hit_condition:
            An expression where `@HIT@` will be replaced by the number of hits.
            i.e.: `@HIT@ == x` or `@HIT@ >= x`

        :param bool is_logpoint:
            If True and an expression is passed, pydevd will create an io message command with the
            result of the evaluation.
        '''
        assert filename.__class__ == str  # i.e.: bytes on py2 and str on py3
        assert func_name.__class__ == str  # i.e.: bytes on py2 and str on py3

        if not pydevd_file_utils.exists(filename):
            sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\
                ' to file that does not exist: %s (will have no effect)\n' % (filename,))
            sys.stderr.flush()
            return

        if breakpoint_type == 'python-line':
            added_breakpoint = LineBreakpoint(line, condition, func_name, expression, suspend_policy, hit_condition=hit_condition, is_logpoint=is_logpoint)
            breakpoints = py_db.breakpoints
            file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
            supported_type = True

        else:
            result = None
            plugin = py_db.get_plugin_lazy_init()
            if plugin is not None:
                result = plugin.add_breakpoint('add_line_breakpoint', py_db, breakpoint_type, filename, line, condition, expression, func_name, hit_condition=hit_condition, is_logpoint=is_logpoint)
            if result is not None:
                supported_type = True
                added_breakpoint, breakpoints = result
                file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
            else:
                supported_type = False

        if not supported_type:
            raise NameError(breakpoint_type)

        if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
            pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n' % (filename, line, func_name))
            sys.stderr.flush()

        if filename in file_to_id_to_breakpoint:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename]
        else:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename] = {}

        id_to_pybreakpoint[breakpoint_id] = added_breakpoint
        py_db.consolidate_breakpoints(filename, id_to_pybreakpoint, breakpoints)
        if py_db.plugin is not None:
            py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

        py_db.on_breakpoints_changed()
Exemple #33
0
    def in_project_roots(self, received_filename):
        '''
        Note: don't call directly. Use PyDb.in_project_scope (there's no caching here and it doesn't
        handle all possibilities for knowing whether a project is actually in the scope, it
        just handles the heuristics based on the absolute_normalized_filename without the actual frame).
        '''
        DEBUG = False

        if received_filename.startswith(USER_CODE_BASENAMES_STARTING_WITH):
            if DEBUG:
                pydev_log.debug(
                    'In in_project_roots - user basenames - starts with %s (%s)',
                    received_filename, USER_CODE_BASENAMES_STARTING_WITH)
            return True

        if received_filename.startswith(LIBRARY_CODE_BASENAMES_STARTING_WITH):
            if DEBUG:
                pydev_log.debug(
                    'Not in in_project_roots - library basenames - starts with %s (%s)',
                    received_filename, LIBRARY_CODE_BASENAMES_STARTING_WITH)
            return False

        project_roots = self._get_project_roots(
        )  # roots are absolute/normalized.

        absolute_normalized_filename = self._absolute_normalized_path(
            received_filename)

        found_in_project = []
        for root in project_roots:
            if root and absolute_normalized_filename.startswith(root):
                if DEBUG:
                    pydev_log.debug('In project: %s (%s)',
                                    absolute_normalized_filename, root)
                found_in_project.append(root)

        found_in_library = []
        library_roots = self._get_library_roots()
        for root in library_roots:
            if root and absolute_normalized_filename.startswith(root):
                found_in_library.append(root)
                if DEBUG:
                    pydev_log.debug('In library: %s (%s)',
                                    absolute_normalized_filename, root)
            else:
                if DEBUG:
                    pydev_log.debug('Not in library: %s (%s)',
                                    absolute_normalized_filename, root)

        if not project_roots:
            # If we have no project roots configured, consider it being in the project
            # roots if it's not found in site-packages (because we have defaults for those
            # and not the other way around).
            in_project = not found_in_library
            if DEBUG:
                pydev_log.debug('Final in project (no project roots): %s (%s)',
                                absolute_normalized_filename, in_project)

        else:
            in_project = False
            if found_in_project:
                if not found_in_library:
                    if DEBUG:
                        pydev_log.debug(
                            'Final in project (in_project and not found_in_library): %s (True)',
                            absolute_normalized_filename)
                    in_project = True
                else:
                    # Found in both, let's see which one has the bigger path matched.
                    if max(len(x) for x in found_in_project) > max(
                            len(x) for x in found_in_library):
                        in_project = True
                    if DEBUG:
                        pydev_log.debug(
                            'Final in project (found in both): %s (%s)',
                            absolute_normalized_filename, in_project)

        return in_project
def stop_on_unhandled_exception(py_db, thread, additional_info, arg):
    from _pydevd_bundle.pydevd_frame import handle_breakpoint_condition, handle_breakpoint_expression
    exctype, value, tb = arg

    if exctype in (KeyboardInterrupt, SystemExit):
        return

    break_on_uncaught_exceptions = py_db.break_on_uncaught_exceptions
    if break_on_uncaught_exceptions:
        exception_breakpoint = get_exception_breakpoint(
            exctype, break_on_uncaught_exceptions)
    else:
        exception_breakpoint = None

    original_excepthook(exctype, value, tb)
    disable_excepthook()  # Avoid printing the exception for the second time.

    if not exception_breakpoint:
        return

    if tb is None:  # sometimes it can be None, e.g. with GTK
        return

    frames = []
    user_frame = None

    while tb:
        frame = tb.tb_frame
        if exception_breakpoint.ignore_libraries and py_db.in_project_scope(
                frame.f_code.co_filename):
            user_frame = tb.tb_frame
        frames.append(tb.tb_frame)
        tb = tb.tb_next

    frames_byid = dict([(id(frame), frame) for frame in frames])
    if exception_breakpoint.ignore_libraries and user_frame is not None:
        frame = user_frame
    else:
        frame = frames[-1]
    add_exception_to_frame(frame, arg)
    if exception_breakpoint.condition is not None:
        eval_result = handle_breakpoint_condition(py_db, additional_info,
                                                  exception_breakpoint, frame)
        if not eval_result:
            return

    if exception_breakpoint.expression is not None:
        handle_breakpoint_expression(exception_breakpoint, additional_info,
                                     frame)

    try:
        additional_info.pydev_message = exception_breakpoint.qname
    except:
        additional_info.pydev_message = exception_breakpoint.qname.encode(
            'utf-8')

    additional_info.pydev_message = 'python-%s' % additional_info.pydev_message

    pydev_log.debug('Handling post-mortem stop on exception breakpoint %s' %
                    (exception_breakpoint.qname, ))

    py_db.stop_on_unhandled_exception(thread, frame, frames_byid, arg)
Exemple #35
0
    def _on_run(self):
        try:
            content_len = -1

            while not self.killReceived:
                try:
                    line = self._read_line()

                    if len(line) == 0:
                        self.handle_except()
                        return  # Finished communication.

                    if line.startswith(b'Content-Length:'):
                        content_len = int(line.strip().split(b':', 1)[1])
                        continue

                    if content_len != -1:
                        # If we previously received a content length, read until a '\r\n'.
                        if line == b'\r\n':
                            json_contents = self._read(content_len)
                            content_len = -1

                            if len(json_contents) == 0:
                                self.handle_except()
                                return  # Finished communication.

                            # We just received a json message, let's process it.
                            self.process_net_command_json(self.global_debugger_holder.global_dbg, json_contents)

                        continue
                    else:
                        # No content len, regular line-based protocol message (remove trailing new-line).
                        if line.endswith(b'\n\n'):
                            line = line[:-2]

                        elif line.endswith(b'\n'):
                            line = line[:-1]

                        elif line.endswith(b'\r'):
                            line = line[:-1]
                except:
                    if not self.killReceived:
                        traceback.print_exc()
                        self.handle_except()
                    return  # Finished communication.


                # Note: the java backend is always expected to pass utf-8 encoded strings. We now work with unicode
                # internally and thus, we may need to convert to the actual encoding where needed (i.e.: filenames
                # on python 2 may need to be converted to the filesystem encoding).
                if hasattr(line, 'decode'):
                    line = line.decode('utf-8')

                if DebugInfoHolder.DEBUG_RECORD_SOCKET_READS:
                    sys.stderr.write(u'debugger: received >>%s<<\n' % (line,))
                    sys.stderr.flush()


                args = line.split(u'\t', 2)
                try:
                    cmd_id = int(args[0])
                    pydev_log.debug('Received command: %s %s\n' % (ID_TO_MEANING.get(str(cmd_id), '???'), line,))
                    self.process_command(cmd_id, int(args[1]), args[2])
                except:
                    if traceback is not None and sys is not None:  # Could happen at interpreter shutdown
                        traceback.print_exc()
                        sys.stderr.write("Can't process net command: %s\n" % line)
                        sys.stderr.flush()

        except:
            if not self.killReceived:
                if traceback is not None:  # Could happen at interpreter shutdown
                    traceback.print_exc()
            self.handle_except()
    def trace_dispatch(self, frame, event, arg):
        # ENDIF

        main_debugger, filename, info, thread, frame_skips_cache, frame_cache_key = self._args

        # print('frame trace_dispatch %s %s %s %s %s' % (frame.f_lineno, frame.f_code.co_name, frame.f_code.co_filename, event, info.pydev_step_cmd))

        # The thread can be already suspended by another function, e.g. built-in breakpoint hook.
        if info.is_tracing:
            return None

        try:
            info.is_tracing = True
            line = frame.f_lineno
            line_cache_key = (frame_cache_key, line)

            if main_debugger._finish_debugging_session:
                if event != 'call': frame.f_trace = NO_FTRACE
                return None

            # IFDEF CYTHON
            # if event == 'opcode':
            #     instructions = self._get_instructions(frame)
            #     for i, inst in enumerate(instructions):
            #         if inst.offset == frame.f_lasti:
            #             opname, arg, argval = inst.opname, inst.arg, str(inst.argval)
            #             print('frame trace_dispatch %s %s %s %s %s %s %s %s' % (frame.f_lineno, frame.f_lasti, frame.f_code.co_name,
            #                                                                     frame.f_code.co_filename, event, opname, arg, argval))
            #             try:
            #                 self._bytecode_offset = instructions[i + 1].offset
            #             except IndexError:
            #                 break
            #     return self.trace_dispatch
            # ENDIF

            plugin_manager = main_debugger.plugin

            is_exception_event = event == 'exception'
            has_exception_breakpoints = main_debugger.break_on_caught_exceptions or main_debugger.has_plugin_exception_breaks \
                or main_debugger.stop_on_failed_tests

            if is_exception_event:
                if has_exception_breakpoints:
                    should_stop, frame = self.should_stop_on_exception(
                        frame, event, arg)
                    if should_stop:
                        self.handle_exception(frame, event, arg)
                        # No need to reset frame.f_trace to keep the same trace function.
                        return self.trace_dispatch
                is_line = False
                is_return = False
                is_call = False
            else:
                is_line = event == 'line'
                is_return = event == 'return'
                is_call = event == 'call'
                if not is_line and not is_return and not is_call:
                    # Unexpected: just keep the same trace func.
                    # No need to reset frame.f_trace to keep the same trace function.
                    return self.trace_dispatch

            need_signature_trace_return = False
            if main_debugger.signature_factory is not None:
                if is_call:
                    need_signature_trace_return = send_signature_call_trace(
                        main_debugger, frame, filename)
                elif is_return:
                    send_signature_return_trace(main_debugger, frame, filename,
                                                arg)

            stop_frame = info.pydev_step_stop
            step_cmd = info.pydev_step_cmd
            is_generator_or_coroutime = frame.f_code.co_flags & 0xa0  # 0xa0 ==  CO_GENERATOR = 0x20 | CO_COROUTINE = 0x80

            breakpoints_for_file = main_debugger.breakpoints.get(filename)

            if not is_exception_event:
                if is_generator_or_coroutime:
                    if is_return:
                        # Dealing with coroutines and generators:
                        # When in a coroutine we change the perceived event to the debugger because
                        # a call, StopIteration exception and return are usually just pausing/unpausing it.
                        returns_cache_key = (frame_cache_key, 'returns')
                        return_lines = frame_skips_cache.get(returns_cache_key)
                        if return_lines is None:
                            # Note: we're collecting the return lines by inspecting the bytecode as
                            # there are multiple returns and multiple stop iterations when awaiting and
                            # it doesn't give any clear indication when a coroutine or generator is
                            # finishing or just pausing.
                            return_lines = set()
                            for x in main_debugger.collect_return_info(
                                    frame.f_code):
                                # Note: cython does not support closures in cpdefs (so we can't use
                                # a list comprehension).
                                return_lines.add(x.return_line)

                            frame_skips_cache[returns_cache_key] = return_lines

                        if line not in return_lines:
                            # Not really a return (coroutine/generator paused).
                            return self.trace_dispatch
                    elif is_call:
                        # Don't stop when calling coroutines, we will on other event anyway if necessary.
                        return self.trace_dispatch

                can_skip = False

                if info.pydev_state == 1:  # STATE_RUN = 1
                    # we can skip if:
                    # - we have no stop marked
                    # - we should make a step return/step over and we're not in the current frame
                    # CMD_STEP_RETURN = 109, CMD_STEP_OVER = 108
                    can_skip = (step_cmd == -1 and stop_frame is None) \
                               or (step_cmd in (109, 108) and stop_frame is not frame)

                    if can_skip:
                        if plugin_manager is not None and main_debugger.has_plugin_line_breaks:
                            can_skip = not plugin_manager.can_not_skip(
                                main_debugger, self, frame, info)

                        # CMD_STEP_OVER = 108
                        if can_skip and main_debugger.show_return_values and info.pydev_step_cmd == 108 and frame.f_back is info.pydev_step_stop:
                            # trace function for showing return values after step over
                            can_skip = False

                # Let's check to see if we are in a function that has a breakpoint. If we don't have a breakpoint,
                # we will return nothing for the next trace
                # also, after we hit a breakpoint and go to some other debugging state, we have to force the set trace anyway,
                # so, that's why the additional checks are there.
                if not breakpoints_for_file:
                    if can_skip:
                        if has_exception_breakpoints:
                            frame.f_trace = self.trace_exception
                            return self.trace_exception
                        else:
                            if need_signature_trace_return:
                                frame.f_trace = self.trace_return
                                return self.trace_return
                            else:
                                if not is_call: frame.f_trace = NO_FTRACE
                                return None

                else:
                    # When cached, 0 means we don't have a breakpoint and 1 means we have.
                    if can_skip:
                        breakpoints_in_line_cache = frame_skips_cache.get(
                            line_cache_key, -1)
                        if breakpoints_in_line_cache == 0:
                            # No need to reset frame.f_trace to keep the same trace function.
                            return self.trace_dispatch

                    breakpoints_in_frame_cache = frame_skips_cache.get(
                        frame_cache_key, -1)
                    if breakpoints_in_frame_cache != -1:
                        # Gotten from cache.
                        has_breakpoint_in_frame = breakpoints_in_frame_cache == 1

                    else:
                        has_breakpoint_in_frame = False
                        # Checks the breakpoint to see if there is a context match in some function
                        curr_func_name = frame.f_code.co_name

                        # global context is set with an empty name
                        if curr_func_name in ('?', '<module>', '<lambda>'):
                            curr_func_name = ''

                        for breakpoint in dict_iter_values(
                                breakpoints_for_file
                        ):  # jython does not support itervalues()
                            # will match either global or some function
                            if breakpoint.func_name in ('None',
                                                        curr_func_name):
                                has_breakpoint_in_frame = True
                                break

                        # Cache the value (1 or 0 or -1 for default because of cython).
                        if has_breakpoint_in_frame:
                            frame_skips_cache[frame_cache_key] = 1
                        else:
                            frame_skips_cache[frame_cache_key] = 0

                    if can_skip and not has_breakpoint_in_frame:
                        if has_exception_breakpoints:
                            frame.f_trace = self.trace_exception
                            return self.trace_exception
                        else:
                            if need_signature_trace_return:
                                frame.f_trace = self.trace_return
                                return self.trace_return
                            else:
                                if not is_call: frame.f_trace = NO_FTRACE
                                return None

            # We may have hit a breakpoint or we are already in step mode. Either way, let's check what we should do in this frame
            # print('NOT skipped: %s %s %s %s' % (frame.f_lineno, frame.f_code.co_name, event, frame.__class__.__name__))
            try:
                flag = False
                # return is not taken into account for breakpoint hit because we'd have a double-hit in this case
                # (one for the line and the other for the return).

                stop_info = {}
                breakpoint = None
                exist_result = False
                stop = False
                bp_type = None
                smart_stop_frame = info.pydev_smart_step_context.smart_step_stop
                context_start_line = info.pydev_smart_step_context.start_line
                context_end_line = info.pydev_smart_step_context.end_line
                is_within_context = context_start_line <= line <= context_end_line

                if not is_return and info.pydev_state != STATE_SUSPEND and breakpoints_for_file is not None and line in breakpoints_for_file:
                    breakpoint = breakpoints_for_file[line]
                    new_frame = frame
                    stop = True
                    if step_cmd == CMD_STEP_OVER:
                        if stop_frame is frame and (is_line or is_return):
                            stop = False  # we don't stop on breakpoint if we have to stop by step-over (it will be processed later)
                        elif is_generator_or_coroutime and frame.f_back and frame.f_back is stop_frame:
                            stop = False  # we don't stop on breakpoint if stepping is active and we enter a `genexpr` or coroutine context
                    elif step_cmd == CMD_SMART_STEP_INTO and (
                            frame.f_back is smart_stop_frame
                            and is_within_context):
                        stop = False
                elif plugin_manager is not None and main_debugger.has_plugin_line_breaks:
                    result = plugin_manager.get_breakpoint(
                        main_debugger, self, frame, event, self._args)
                    if result:
                        exist_result = True
                        flag, breakpoint, new_frame, bp_type = result

                if breakpoint:
                    # ok, hit breakpoint, now, we have to discover if it is a conditional breakpoint
                    # lets do the conditional stuff here
                    if stop or exist_result:
                        eval_result = False
                        if breakpoint.has_condition:
                            eval_result = handle_breakpoint_condition(
                                main_debugger, info, breakpoint, new_frame)

                        if breakpoint.expression is not None:
                            handle_breakpoint_expression(
                                breakpoint, info, new_frame)
                            if breakpoint.is_logpoint and info.pydev_message is not None and len(
                                    info.pydev_message) > 0:
                                cmd = main_debugger.cmd_factory.make_io_message(
                                    info.pydev_message + os.linesep, '1')
                                main_debugger.writer.add_command(cmd)

                        if breakpoint.has_condition and not eval_result:
                            # No need to reset frame.f_trace to keep the same trace function.
                            return self.trace_dispatch

                    if is_call and frame.f_code.co_name in ('<module>',
                                                            '<lambda>'):
                        # If we find a call for a module, it means that the module is being imported/executed for the
                        # first time. In this case we have to ignore this hit as it may later duplicated by a
                        # line event at the same place (so, if there's a module with a print() in the first line
                        # the user will hit that line twice, which is not what we want).
                        #
                        # As for lambda, as it only has a single statement, it's not interesting to trace
                        # its call and later its line event as they're usually in the same line.

                        # No need to reset frame.f_trace to keep the same trace function.
                        return self.trace_dispatch

                else:
                    # if the frame is traced after breakpoint stop,
                    # but the file should be ignored while stepping because of filters
                    if step_cmd != -1:
                        if main_debugger.is_filter_enabled and main_debugger.is_ignored_by_filters(
                                filename):
                            # ignore files matching stepping filters
                            # No need to reset frame.f_trace to keep the same trace function.
                            return self.trace_dispatch
                        if main_debugger.is_filter_libraries and not main_debugger.in_project_scope(
                                filename):
                            # ignore library files while stepping
                            # No need to reset frame.f_trace to keep the same trace function.
                            return self.trace_dispatch

                if main_debugger.show_return_values or main_debugger.remove_return_values_flag:
                    self.manage_return_values(main_debugger, frame, event, arg)

                if stop:
                    self.set_suspend(
                        thread,
                        CMD_SET_BREAK,
                        suspend_other_threads=breakpoint
                        and breakpoint.suspend_policy == "ALL",
                    )

                elif flag and plugin_manager is not None:
                    result = plugin_manager.suspend(main_debugger, thread,
                                                    frame, bp_type)
                    if result:
                        frame = result

                # if thread has a suspend flag, we suspend with a busy wait
                if info.pydev_state == STATE_SUSPEND:
                    self.do_wait_suspend(thread, frame, event, arg)
                    # No need to reset frame.f_trace to keep the same trace function.
                    return self.trace_dispatch
                else:
                    if not breakpoint and is_line:
                        # No stop from anyone and no breakpoint found in line (cache that).
                        frame_skips_cache[line_cache_key] = 0
            except KeyboardInterrupt:
                self.clear_run_state(info)
                raise
            except:
                traceback.print_exc()
                raise

            # step handling. We stop when we hit the right frame
            try:
                should_skip = 0

                if pydevd_dont_trace.should_trace_hook is not None:
                    if self.should_skip == -1:
                        # I.e.: cache the result on self.should_skip (no need to evaluate the same frame multiple times).
                        # Note that on a code reload, we won't re-evaluate this because in practice, the frame.f_code
                        # Which will be handled by this frame is read-only, so, we can cache it safely.
                        if not pydevd_dont_trace.should_trace_hook(
                                frame, filename):
                            # -1, 0, 1 to be Cython-friendly
                            should_skip = self.should_skip = 1
                        else:
                            should_skip = self.should_skip = 0
                    else:
                        should_skip = self.should_skip

                plugin_stop = False
                if should_skip:
                    stop = False

                elif step_cmd == CMD_SMART_STEP_INTO:
                    stop = False
                    if smart_stop_frame is frame:
                        if not is_within_context or not IS_CPYTHON:
                            # We don't stop on jumps in multiline statements, which the Python interpreter does in some cases,
                            # if we they happen in smart step into context.
                            info.pydev_func_name = '.invalid.'  # Must match the type in cython
                            stop = True  # act as if we did a step into

                    if is_line or is_exception_event:
                        curr_func_name = frame.f_code.co_name

                        # global context is set with an empty name
                        if curr_func_name in (
                                '?', '<module>') or curr_func_name is None:
                            curr_func_name = ''

                        if smart_stop_frame and smart_stop_frame is frame.f_back:
                            if curr_func_name == info.pydev_func_name and not IS_CPYTHON:
                                # for implementations other than CPython we don't perform any additional checks
                                stop = True
                            else:
                                try:
                                    if curr_func_name != info.pydev_func_name and frame.f_back:
                                        # try to find function call name using bytecode analysis
                                        curr_func_name = find_last_call_name(
                                            frame.f_back)
                                    if curr_func_name == info.pydev_func_name:
                                        stop = find_last_func_call_order(frame.f_back, context_start_line) \
                                               == info.pydev_smart_step_context.call_order
                                except:
                                    pydev_log.debug(
                                        "Exception while handling smart step into in frame tracer, step into will be performed instead."
                                    )
                                    info.pydev_smart_step_context.reset()
                                    stop = True  # act as if we did a step into

                    # we have to check this case for situations when a user has tried to step into a native function or method,
                    # e.g. `len()`, `list.append()`, etc and this was the only call in a return statement
                    if smart_stop_frame is frame and is_return:
                        stop = True

                elif step_cmd == CMD_STEP_INTO:
                    stop = is_line or is_return
                    if plugin_manager is not None:
                        result = plugin_manager.cmd_step_into(
                            main_debugger, frame, event, self._args, stop_info,
                            stop)
                        if result:
                            stop, plugin_stop = result

                elif step_cmd == CMD_STEP_INTO_MY_CODE:
                    if main_debugger.in_project_scope(
                            frame.f_code.co_filename):
                        stop = is_line

                elif step_cmd in (CMD_STEP_OVER, CMD_STEP_INTO_COROUTINE):
                    stop = stop_frame is frame
                    if stop:
                        if is_line:
                            # the only case we shouldn't stop on a line, is when we traversing though asynchronous framework machinery
                            if step_cmd == CMD_STEP_INTO_COROUTINE:
                                stop = main_debugger.in_project_scope(
                                    frame.f_code.co_filename)
                        elif is_return:
                            stop = frame.f_back and main_debugger.in_project_scope(
                                frame.f_back.f_code.co_filename)
                            if not stop:
                                back = frame.f_back
                                if back:
                                    info.pydev_step_stop = back
                                    if main_debugger.in_project_scope(
                                            frame.f_code.co_filename):
                                        # we are returning from the project scope, step over should always lead to the project scope
                                        if is_generator_or_coroutime and step_cmd == CMD_STEP_OVER:
                                            # setting ad hoc command to ensure we will skip line stops in an asynchronous framework
                                            info.pydev_step_cmd = CMD_STEP_INTO_COROUTINE
                                    else:
                                        # we were already outside the project scope because of step into or breakpoint, it's ok to stop
                                        # if we are not chopping a way through an asynchronous framework
                                        stop = not step_cmd == CMD_STEP_INTO_COROUTINE
                                else:
                                    # if there's no back frame, we just stop as soon as possible
                                    info.pydev_step_cmd = CMD_STEP_INTO
                                    info.pydev_step_stop = None
                        else:
                            stop = False

                    if CMD_STEP_OVER and plugin_manager is not None:
                        result = plugin_manager.cmd_step_over(
                            main_debugger, frame, event, self._args, stop_info,
                            stop)
                        if result:
                            stop, plugin_stop = result

                elif step_cmd == CMD_STEP_RETURN:
                    stop = is_return and stop_frame is frame

                else:
                    stop = False

                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)
                        file_type = get_file_type(back_filename)
                        if file_type == PYDEV_FILE:
                            stop = False

                if plugin_stop:
                    stopped_on_plugin = plugin_manager.stop(
                        main_debugger, frame, event, self._args, stop_info,
                        arg, step_cmd)
                elif stop:
                    if is_line:
                        self.set_suspend(thread, step_cmd)
                        self.do_wait_suspend(thread, frame, event, arg)
                    else:  # return event
                        back = frame.f_back
                        if back is not None:
                            # When we get to the pydevd run function, the debugging has actually finished for the main thread
                            # (note that it can still go on for other threads, but for this one, we just make it finish)
                            # So, just setting it to None should be OK
                            _, back_filename, base = get_abs_path_real_path_and_base_from_frame(
                                back)
                            if (base,
                                    back.f_code.co_name) in (DEBUG_START,
                                                             DEBUG_START_PY3K):
                                back = None

                            elif base == TRACE_PROPERTY:
                                # We dont want to trace the return event of pydevd_traceproperty (custom property for debugging)
                                # if we're in a return, we want it to appear to the user in the previous frame!
                                if not is_call: frame.f_trace = NO_FTRACE
                                return None

                            elif pydevd_dont_trace.should_trace_hook is not None:
                                if not pydevd_dont_trace.should_trace_hook(
                                        back, back_filename):
                                    # In this case, we'll have to skip the previous one because it shouldn't be traced.
                                    # Also, we have to reset the tracing, because if the parent's parent (or some
                                    # other parent) has to be traced and it's not currently, we wouldn't stop where
                                    # we should anymore (so, a step in/over/return may not stop anywhere if no parent is traced).
                                    # Related test: _debugger_case17a.py
                                    main_debugger.set_trace_for_frame_and_parents(
                                        back)
                                    if not is_call: frame.f_trace = NO_FTRACE
                                    return None

                        if back is not None:
                            # if we're in a return, we want it to appear to the user in the previous frame!
                            self.set_suspend(thread, step_cmd)
                            self.do_wait_suspend(thread, back, event, arg)
                        else:
                            # in jython we may not have a back frame
                            self.clear_run_state(info)

            except KeyboardInterrupt:
                self.clear_run_state(info)
                raise
            except:
                try:
                    traceback.print_exc()
                    info.pydev_step_cmd = -1
                except:
                    if not is_call: frame.f_trace = NO_FTRACE
                    return None

            # if we are quitting, let's stop the tracing
            if not main_debugger.quitting:
                # No need to reset frame.f_trace to keep the same trace function.
                return self.trace_dispatch
            else:
                if not is_call: frame.f_trace = NO_FTRACE
                return None
        finally:
            info.is_tracing = False
Exemple #37
0
def _patch_threading_to_hide_pydevd_threads():
    '''
    Patches the needed functions on the `threading` module so that the pydevd threads are hidden.

    Note that we patch the functions __code__ to avoid issues if some code had already imported those
    variables prior to the patching.
    '''
    found_load_names = _collect_load_names(threading.enumerate)
    # i.e.: we'll only apply the patching if the function seems to be what we expect.

    new_threading_enumerate = None

    if found_load_names == set(
        ('_active_limbo_lock', '_limbo', '_active', 'values', 'list')):
        pydev_log.debug(
            'Applying patching to hide pydevd threads (Py3 version).')

        def new_threading_enumerate():
            with _active_limbo_lock:
                ret = list(_active.values()) + list(_limbo.values())

            return [
                t for t in ret
                if not getattr(t, 'is_pydev_daemon_thread', False)
            ]

    elif found_load_names == set(
        ('_active_limbo_lock', '_limbo', '_active', 'values')):
        pydev_log.debug(
            'Applying patching to hide pydevd threads (Py2 version).')

        def new_threading_enumerate():
            with _active_limbo_lock:
                ret = _active.values() + _limbo.values()

            return [
                t for t in ret
                if not getattr(t, 'is_pydev_daemon_thread', False)
            ]

    else:
        pydev_log.info(
            'Unable to hide pydevd threads. Found names in threading.enumerate: %s',
            found_load_names)

    if new_threading_enumerate is not None:

        def pydevd_saved_threading_enumerate():
            with threading._active_limbo_lock:
                return list(threading._active.values()) + list(
                    threading._limbo.values())

        _pydev_saved_modules.pydevd_saved_threading_enumerate = pydevd_saved_threading_enumerate

        threading.enumerate.__code__ = new_threading_enumerate.__code__

        # We also need to patch the active count (to match what we have in the enumerate).
        def new_active_count():
            # Note: as this will be executed in the `threading` module, `enumerate` will
            # actually be threading.enumerate.
            return len(enumerate())

        threading.active_count.__code__ = new_active_count.__code__

        # When shutting down, Python (on some versions) may do something as:
        #
        # def _pickSomeNonDaemonThread():
        #     for t in enumerate():
        #         if not t.daemon and t.is_alive():
        #             return t
        #     return None
        #
        # But in this particular case, we do want threads with `is_pydev_daemon_thread` to appear
        # explicitly due to the pydevd `CheckAliveThread` (because we want the shutdown to wait on it).
        # So, it can't rely on the `enumerate` for that anymore as it's patched to not return pydevd threads.
        if hasattr(threading, '_pickSomeNonDaemonThread'):

            def new_pick_some_non_daemon_thread():
                with _active_limbo_lock:
                    # Ok for py2 and py3.
                    threads = list(_active.values()) + list(_limbo.values())

                for t in threads:
                    if not t.daemon and t.is_alive():
                        return t
                return None

            threading._pickSomeNonDaemonThread.__code__ = new_pick_some_non_daemon_thread.__code__
def patch_args(args, is_exec=False):
    '''
    :param list args:
        Arguments to patch.

    :param bool is_exec:
        If it's an exec, the current process will be replaced (this means we have
        to keep the same ppid).
    '''
    try:
        pydev_log.debug("Patching args: %s", args)
        original_args = args
        args = remove_quotes_from_args(args)

        from pydevd import SetupHolder
        new_args = []
        if len(args) == 0:
            return original_args

        if is_python(args[0]):
            ind_c = get_c_option_index(args)

            if ind_c != -1:
                host, port = _get_host_port()

                if port is not None:
                    new_args.extend(args)
                    new_args[ind_c + 1] = _get_python_c_args(
                        host, port, ind_c, args, SetupHolder.setup)
                    return quote_args(new_args)
            else:
                # Check for Python ZIP Applications and don't patch the args for them.
                # Assumes the first non `-<flag>` argument is what we need to check.
                # There's probably a better way to determine this but it works for most cases.
                continue_next = False
                for i in range(1, len(args)):
                    if continue_next:
                        continue_next = False
                        continue

                    arg = args[i]
                    if arg.startswith(_get_str_type_compatible(arg, '-')):
                        # Skip the next arg too if this flag expects a value.
                        continue_next = arg in _get_str_type_compatible(
                            arg, ['-m', '-W', '-X'])
                        continue

                    dot = _get_str_type_compatible(arg, '.')
                    extensions = _get_str_type_compatible(
                        arg, ['zip', 'pyz', 'pyzw'])
                    if arg.rsplit(dot)[-1] in extensions:
                        pydev_log.debug('Executing a PyZip, returning')
                        return original_args
                    break

                new_args.append(args[0])
        else:
            pydev_log.debug("Process is not python, returning.")
            return original_args

        i = 1
        # Original args should be something as:
        # ['X:\\pysrc\\pydevd.py', '--multiprocess', '--print-in-debugger-startup',
        #  '--vm_type', 'python', '--client', '127.0.0.1', '--port', '56352', '--file', 'x:\\snippet1.py']
        from _pydevd_bundle.pydevd_command_line_handling import setup_to_argv
        original = setup_to_argv(
            _get_setup_updated_with_protocol_and_ppid(
                SetupHolder.setup, is_exec=is_exec)) + ['--file']

        module_name = None
        m_flag = _get_str_type_compatible(args[i], '-m')
        while i < len(args):
            if args[i] == m_flag:
                # Always insert at pos == 1 (i.e.: pydevd "--module" --multiprocess ...)
                original.insert(1, '--module')
            elif args[i].startswith(m_flag):
                # Case where the user does: python -mmodule_name (using a single parameter).
                original.insert(1, '--module')
                module_name = args[i][2:]
            else:
                if args[i].startswith(_get_str_type_compatible(args[i], '-')):
                    new_args.append(args[i])
                else:
                    break
            i += 1

        # Note: undoing https://github.com/Elizaveta239/PyDev.Debugger/commit/053c9d6b1b455530bca267e7419a9f63bf51cddf
        # (i >= len(args) instead of i < len(args))
        # in practice it'd raise an exception here and would return original args, which is not what we want... providing
        # a proper fix for https://youtrack.jetbrains.com/issue/PY-9767 elsewhere.
        if i < len(args) and _is_managed_arg(
                args[i]):  # no need to add pydevd twice
            return original_args

        for x in original:
            new_args.append(x)
            if x == _get_str_type_compatible(x, '--file'):
                break

        if module_name is not None:
            new_args.append(module_name)

        while i < len(args):
            new_args.append(args[i])
            i += 1

        return quote_args(new_args)
    except:
        pydev_log.exception('Error patching args')
        return original_args
Exemple #39
0
 def set_use_libraries_filter(self, use):
     pydev_log.debug("pydevd: Use libraries filter: %s\n" % use)
     self._use_libraries_filter = use
Exemple #40
0
def is_filter_libraries():
    is_filter = os.getenv('PYDEVD_FILTER_LIBRARIES') is not None
    pydev_log.debug("PYDEVD_FILTER_LIBRARIES %s\n" % is_filter)
    return is_filter
Exemple #41
0
 def set_library_roots(self, roots):
     self._library_roots = self._fix_roots(roots)
     pydev_log.debug("LIBRARY_ROOTS %s\n" % roots)
 def set_library_roots(self, roots):
     self._library_roots = self._fix_roots(roots)
     pydev_log.debug("LIBRARY_ROOTS %s\n" % roots)
import types

from _pydev_bundle import pydev_log
from _pydevd_bundle import pydevd_trace_api

try:
    from pydevd_plugins import django_debug
except:
    django_debug = None
    pydev_log.debug('Unable to load django_debug plugin')

try:
    from pydevd_plugins import jinja2_debug
except:
    jinja2_debug = None
    pydev_log.debug('Unable to load jinja2_debug plugin')

def load_plugins():
    plugins = []
    if django_debug is not None:
        plugins.append(django_debug)

    if jinja2_debug is not None:
        plugins.append(jinja2_debug)
    return plugins


def bind_func_to_method(func, obj, method_name):
    bound_method = types.MethodType(func, obj)

    setattr(obj, method_name, bound_method)
Exemple #44
0
    def should_stop_on_exception(self, frame, event, arg):
        # ENDIF

        # main_debugger, _filename, info, _thread = self._args
        main_debugger = self._args[0]
        info = self._args[2]
        should_stop = False

        # STATE_SUSPEND = 2
        if info.pydev_state != 2:  #and breakpoint is not None:
            exception, value, trace = arg

            if trace is not None and hasattr(trace, 'tb_next'):
                # on jython trace is None on the first event and it may not have a tb_next.

                exception_breakpoint = get_exception_breakpoint(
                    exception, main_debugger.break_on_caught_exceptions)

                if exception_breakpoint is not None:
                    if exception_breakpoint.condition is not None:
                        eval_result = handle_breakpoint_condition(
                            main_debugger, info, exception_breakpoint, frame)
                        if not eval_result:
                            return False, frame

                    if exception_breakpoint.ignore_libraries:
                        if not main_debugger.is_exception_trace_in_project_scope(
                                trace):
                            pydev_log.debug(
                                "Ignore exception %s in library %s -- (%s)" %
                                (exception, frame.f_code.co_filename,
                                 frame.f_code.co_name))
                            return False, frame

                    if ignore_exception_trace(trace):
                        return False, frame

                    was_just_raised = just_raised(trace)
                    if was_just_raised:

                        if main_debugger.skip_on_exceptions_thrown_in_same_context:
                            # Option: Don't break if an exception is caught in the same function from which it is thrown
                            return False, frame

                    if exception_breakpoint.notify_on_first_raise_only:
                        if main_debugger.skip_on_exceptions_thrown_in_same_context:
                            # In this case we never stop if it was just raised, so, to know if it was the first we
                            # need to check if we're in the 2nd method.
                            if not was_just_raised and not just_raised(
                                    trace.tb_next):
                                return False, frame  # I.e.: we stop only when we're at the caller of a method that throws an exception

                        else:
                            if not was_just_raised:
                                return False, frame  # I.e.: we stop only when it was just raised

                    # If it got here we should stop.
                    should_stop = True
                    try:
                        info.pydev_message = exception_breakpoint.qname
                    except:
                        info.pydev_message = exception_breakpoint.qname.encode(
                            'utf-8')

                    # Always add exception to frame (must remove later after we proceed).
                    add_exception_to_frame(frame, (exception, value, trace))

                else:
                    # No regular exception breakpoint, let's see if some plugin handles it.
                    try:
                        if main_debugger.plugin is not None:
                            result = main_debugger.plugin.exception_break(
                                main_debugger, self, frame, self._args, arg)
                            if result:
                                should_stop, frame = result
                    except:
                        should_stop = False

                if should_stop:
                    if exception_breakpoint is not None and exception_breakpoint.expression is not None:
                        handle_breakpoint_expression(exception_breakpoint,
                                                     info, frame)

        return should_stop, frame
Exemple #45
0
 def set_project_roots(self, project_roots):
     self._project_roots = self._fix_roots(project_roots)
     pydev_log.debug("IDE_PROJECT_ROOTS %s\n" % project_roots)
Exemple #46
0
def log_debug(msg):
    pydev_log.debug(msg)
def process_net_command(py_db, cmd_id, seq, text):
    '''Processes a command received from the Java side

    @param cmd_id: the id of the command
    @param seq: the sequence of the command
    @param text: the text received in the command

    @note: this method is run as a big switch... after doing some tests, it's not clear whether changing it for
    a dict id --> function call will have better performance result. A simple test with xrange(10000000) showed
    that the gains from having a fast access to what should be executed are lost because of the function call in
    a way that if we had 10 elements in the switch the if..elif are better -- but growing the number of choices
    makes the solution with the dispatch look better -- so, if this gets more than 20-25 choices at some time,
    it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before
    probably will give better performance).
    '''
    # print(ID_TO_MEANING[str(cmd_id)], repr(text))

    py_db._main_lock.acquire()
    try:
        try:
            cmd = None
            if cmd_id == CMD_RUN:
                py_db.ready_to_run = True

            elif cmd_id == CMD_SET_PROTOCOL:
                expected = (NetCommand.HTTP_PROTOCOL,
                            NetCommand.QUOTED_LINE_PROTOCOL)
                text = text.strip()
                assert text.strip(
                ) in expected, 'Protocol (%s) should be one of: %s' % (
                    text, expected)

                NetCommand.protocol = text
                cmd = py_db.cmd_factory.make_protocol_set_message(seq)

            elif cmd_id == CMD_VERSION:
                # response is version number
                # ide_os should be 'WINDOWS' or 'UNIX'.

                # Default based on server process (although ideally the IDE should
                # provide it).
                if IS_WINDOWS:
                    ide_os = 'WINDOWS'
                else:
                    ide_os = 'UNIX'

                # Breakpoints can be grouped by 'LINE' or by 'ID'.
                breakpoints_by = 'LINE'

                splitted = text.split('\t')
                if len(splitted) == 1:
                    _local_version = splitted

                elif len(splitted) == 2:
                    _local_version, ide_os = splitted

                elif len(splitted) == 3:
                    _local_version, ide_os, breakpoints_by = splitted

                if breakpoints_by == 'ID':
                    py_db._set_breakpoints_with_id = True
                else:
                    py_db._set_breakpoints_with_id = False

                pydevd_file_utils.set_ide_os(ide_os)

                cmd = py_db.cmd_factory.make_version_message(seq)

            elif cmd_id == CMD_LIST_THREADS:
                # response is a list of threads
                cmd = py_db.cmd_factory.make_list_threads_message(seq)

            elif cmd_id == CMD_GET_THREAD_STACK:
                # Receives a thread_id and a given timeout, which is the time we should
                # wait to the provide the stack if a given thread is still not suspended.
                if '\t' in text:
                    thread_id, timeout = text.split('\t')
                    timeout = float(timeout)
                else:
                    thread_id = text
                    timeout = .5  # Default timeout is .5 seconds

                # If it's already suspended, get it right away.
                internal_get_thread_stack = InternalGetThreadStack(
                    seq,
                    thread_id,
                    py_db,
                    set_additional_thread_info,
                    timeout=timeout)
                if internal_get_thread_stack.can_be_executed_by(
                        get_current_thread_id(threading.current_thread())):
                    internal_get_thread_stack.do_it(py_db)
                else:
                    py_db.post_internal_command(internal_get_thread_stack, '*')

            elif cmd_id == CMD_THREAD_SUSPEND:
                # Yes, thread suspend is done at this point, not through an internal command.
                threads = []
                suspend_all = text.strip() == '*'
                if suspend_all:
                    threads = pydevd_utils.get_non_pydevd_threads()

                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't suspend tasklet: %s\n" % (text, ))

                else:
                    threads = [pydevd_find_thread_by_id(text)]

                for t in threads:
                    if t is None:
                        continue
                    py_db.set_suspend(
                        t,
                        CMD_THREAD_SUSPEND,
                        suspend_other_threads=suspend_all,
                        is_pause=True,
                    )
                    # Break here (even if it's suspend all) as py_db.set_suspend will
                    # take care of suspending other threads.
                    break

            elif cmd_id == CMD_THREAD_RUN:
                threads = []
                if text.strip() == '*':
                    threads = pydevd_utils.get_non_pydevd_threads()

                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't make tasklet run: %s\n" % (text, ))

                else:
                    threads = [pydevd_find_thread_by_id(text)]

                for t in threads:
                    if t is None:
                        continue
                    additional_info = set_additional_thread_info(t)
                    additional_info.pydev_step_cmd = -1
                    additional_info.pydev_step_stop = None
                    additional_info.pydev_state = STATE_RUN

            elif cmd_id == CMD_STEP_INTO or cmd_id == CMD_STEP_OVER or cmd_id == CMD_STEP_RETURN or \
                    cmd_id == CMD_STEP_INTO_MY_CODE:
                # we received some command to make a single step
                t = pydevd_find_thread_by_id(text)
                if t:
                    thread_id = get_thread_id(t)
                    int_cmd = InternalStepThread(thread_id, cmd_id)
                    py_db.post_internal_command(int_cmd, thread_id)

                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't make tasklet step command: %s\n" %
                                     (text, ))

            elif cmd_id in (CMD_RUN_TO_LINE, CMD_SET_NEXT_STATEMENT,
                            CMD_SMART_STEP_INTO):
                if cmd_id == CMD_SMART_STEP_INTO:
                    # we received a smart step into command
                    thread_id, frame_id, line, func_name, call_order, start_line, end_line = text.split(
                        '\t', 6)
                else:
                    # we received some command to make a single step
                    thread_id, line, func_name = text.split('\t', 2)
                if func_name == "None":
                    # global context
                    func_name = ''
                t = pydevd_find_thread_by_id(thread_id)
                if t:
                    if cmd_id == CMD_SMART_STEP_INTO:
                        int_cmd = InternalSmartStepInto(
                            thread_id, frame_id, cmd_id, func_name, line,
                            call_order, start_line, end_line, seq)
                    else:
                        int_cmd = InternalSetNextStatementThread(
                            thread_id, cmd_id, line, func_name, seq)
                    py_db.post_internal_command(int_cmd, thread_id)
                elif thread_id.startswith('__frame__:'):
                    sys.stderr.write(
                        "Can't set next statement in tasklet: %s\n" %
                        (thread_id, ))

            elif cmd_id == CMD_RELOAD_CODE:
                # we received some command to make a reload of a module
                module_name = text.strip()

                thread_id = '*'  # Any thread
                # Note: not going for the main thread because in this case it'd only do the load
                # when we stopped on a breakpoint.
                int_cmd = ReloadCodeCommand(module_name, thread_id)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_CHANGE_VARIABLE:
                # the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change
                try:
                    thread_id, frame_id, scope, attr_and_value = text.split(
                        '\t', 3)

                    tab_index = attr_and_value.rindex('\t')
                    attr = attr_and_value[0:tab_index].replace('\t', '.')
                    value = attr_and_value[tab_index + 1:]
                    int_cmd = InternalChangeVariable(seq, thread_id, frame_id,
                                                     scope, attr, value)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_VARIABLE:
                # we received some command to get a variable
                # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes*
                try:
                    thread_id, frame_id, scopeattrs = text.split('\t', 2)

                    if scopeattrs.find(
                            '\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    int_cmd = InternalGetVariable(seq, thread_id, frame_id,
                                                  scope, attrs)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_ARRAY:
                # we received some command to get an array variable
                # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tname\ttemp\troffs\tcoffs\trows\tcols\tformat
                try:
                    roffset, coffset, rows, cols, format, thread_id, frame_id, scopeattrs = text.split(
                        '\t', 7)

                    if scopeattrs.find(
                            '\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    int_cmd = InternalGetArray(seq, roffset, coffset, rows,
                                               cols, format, thread_id,
                                               frame_id, scope, attrs)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_SHOW_RETURN_VALUES:
                try:
                    show_return_values = text.split('\t')[1]
                    if int(show_return_values) == 1:
                        py_db.show_return_values = True
                    else:
                        if py_db.show_return_values:
                            # We should remove saved return values
                            py_db.remove_return_values_flag = True
                        py_db.show_return_values = False
                    pydev_log.debug("Show return values: %s\n" %
                                    py_db.show_return_values)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_SET_UNIT_TEST_DEBUGGING_MODE:
                py_db.set_unit_tests_debugging_mode()

            elif cmd_id == CMD_LOAD_FULL_VALUE:
                try:
                    thread_id, frame_id, scopeattrs = text.split('\t', 2)
                    vars = scopeattrs.split(NEXT_VALUE_SEPARATOR)

                    int_cmd = InternalLoadFullValue(seq, thread_id, frame_id,
                                                    vars)
                    py_db.post_internal_command(int_cmd, thread_id)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_COMPLETIONS:
                # we received some command to get a variable
                # the text is: thread_id\tframe_id\tactivation token
                try:
                    thread_id, frame_id, scope, act_tok = text.split('\t', 3)

                    int_cmd = InternalGetCompletions(seq, thread_id, frame_id,
                                                     act_tok)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()
            elif cmd_id == CMD_GET_DESCRIPTION:
                try:

                    thread_id, frame_id, expression = text.split('\t', 2)
                    int_cmd = InternalGetDescription(seq, thread_id, frame_id,
                                                     expression)
                    py_db.post_internal_command(int_cmd, thread_id)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_FRAME:
                thread_id, frame_id, scope = text.split('\t', 2)

                int_cmd = InternalGetFrame(seq, thread_id, frame_id)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_BREAK:
                # func name: 'None': match anything. Empty: match global, specified: only method context.
                # command to add some breakpoint.
                # text is file\tline. Add to breakpoints dictionary
                suspend_policy = "NONE"  # Can be 'NONE' or 'ALL'
                is_logpoint = False
                hit_condition = None
                if py_db._set_breakpoints_with_id:
                    try:
                        try:
                            breakpoint_id, type, file, line, func_name, condition, expression, hit_condition, is_logpoint, suspend_policy = text.split(
                                '\t', 9)
                        except ValueError:  # not enough values to unpack
                            # No suspend_policy passed (use default).
                            breakpoint_id, type, file, line, func_name, condition, expression, hit_condition, is_logpoint = text.split(
                                '\t', 8)
                        is_logpoint = is_logpoint == 'True'
                    except ValueError:  # not enough values to unpack
                        breakpoint_id, type, file, line, func_name, condition, expression = text.split(
                            '\t', 6)

                    breakpoint_id = int(breakpoint_id)
                    line = int(line)

                    # We must restore new lines and tabs as done in
                    # AbstractDebugTarget.breakpointAdded
                    condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                    expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()
                else:
                    # Note: this else should be removed after PyCharm migrates to setting
                    # breakpoints by id (and ideally also provides func_name).
                    type, file, line, func_name, suspend_policy, condition, expression = text.split(
                        '\t', 6)
                    # If we don't have an id given for each breakpoint, consider
                    # the id to be the line.
                    breakpoint_id = line = int(line)

                    condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                    expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    file = file.encode(file_system_encoding)

                if pydevd_file_utils.is_real_file(file):
                    file = pydevd_file_utils.norm_file_to_server(file)

                    if not pydevd_file_utils.exists(file):
                        sys.stderr.write(
                            'pydev debugger: warning: trying to add breakpoint'
                            ' to file that does not exist: %s (will have no effect)\n'
                            % (file, ))
                        sys.stderr.flush()

                if condition is not None and (len(condition) <= 0
                                              or condition == "None"):
                    condition = None

                if expression is not None and (len(expression) <= 0
                                               or expression == "None"):
                    expression = None

                if hit_condition is not None and (len(hit_condition) <= 0
                                                  or hit_condition == "None"):
                    hit_condition = None

                if type == 'python-line':
                    breakpoint = LineBreakpoint(line,
                                                condition,
                                                func_name,
                                                expression,
                                                suspend_policy,
                                                hit_condition=hit_condition,
                                                is_logpoint=is_logpoint)
                    breakpoints = py_db.breakpoints
                    file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
                    supported_type = True
                else:
                    result = None
                    plugin = py_db.get_plugin_lazy_init()
                    if plugin is not None:
                        result = plugin.add_breakpoint(
                            'add_line_breakpoint',
                            py_db,
                            type,
                            file,
                            line,
                            condition,
                            expression,
                            func_name,
                            hit_condition=hit_condition,
                            is_logpoint=is_logpoint)
                    if result is not None:
                        supported_type = True
                        breakpoint, breakpoints = result
                        file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
                    else:
                        supported_type = False

                if not supported_type:
                    if type == 'jupyter-line':
                        return
                    else:
                        raise NameError(type)

                if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
                    pydev_log.debug(
                        'Added breakpoint:%s - line:%s - func_name:%s\n' %
                        (file, line, func_name.encode('utf-8')))
                    sys.stderr.flush()

                if file in file_to_id_to_breakpoint:
                    id_to_pybreakpoint = file_to_id_to_breakpoint[file]
                else:
                    id_to_pybreakpoint = file_to_id_to_breakpoint[file] = {}

                id_to_pybreakpoint[breakpoint_id] = breakpoint
                py_db.consolidate_breakpoints(file, id_to_pybreakpoint,
                                              breakpoints)
                if py_db.plugin is not None:
                    py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks(
                    )
                    if py_db.has_plugin_line_breaks:
                        py_db.frame_eval_func = None

                py_db.on_breakpoints_changed()

            elif cmd_id == CMD_REMOVE_BREAK:
                #command to remove some breakpoint
                #text is type\file\tid. Remove from breakpoints dictionary
                breakpoint_type, file, breakpoint_id = text.split('\t', 2)

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    file = file.encode(file_system_encoding)

                if pydevd_file_utils.is_real_file(file):
                    file = pydevd_file_utils.norm_file_to_server(file)

                try:
                    breakpoint_id = int(breakpoint_id)
                except ValueError:
                    pydev_log.error(
                        'Error removing breakpoint. Expected breakpoint_id to be an int. Found: %s'
                        % (breakpoint_id, ))

                else:
                    file_to_id_to_breakpoint = None
                    if breakpoint_type == 'python-line':
                        breakpoints = py_db.breakpoints
                        file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
                    elif py_db.get_plugin_lazy_init() is not None:
                        result = py_db.plugin.get_breakpoints(
                            py_db, breakpoint_type)
                        if result is not None:
                            file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
                            breakpoints = result

                    if file_to_id_to_breakpoint is None:
                        pydev_log.error(
                            'Error removing breakpoint. Cant handle breakpoint of type %s'
                            % breakpoint_type)
                    else:
                        try:
                            id_to_pybreakpoint = file_to_id_to_breakpoint.get(
                                file, {})
                            if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
                                existing = id_to_pybreakpoint[breakpoint_id]
                                sys.stderr.write(
                                    'Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n'
                                    % (file, existing.line,
                                       existing.func_name.encode('utf-8'),
                                       breakpoint_id))

                            del id_to_pybreakpoint[breakpoint_id]
                            py_db.consolidate_breakpoints(
                                file, id_to_pybreakpoint, breakpoints)
                            if py_db.plugin is not None:
                                py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks(
                                )

                        except KeyError:
                            pydev_log.error(
                                "Error removing breakpoint: Breakpoint id not found: %s id: %s. Available ids: %s\n"
                                % (file, breakpoint_id,
                                   dict_keys(id_to_pybreakpoint)))

                py_db.on_breakpoints_changed(removed=True)

            elif cmd_id == CMD_EVALUATE_EXPRESSION or cmd_id == CMD_EXEC_EXPRESSION:
                #command to evaluate the given expression
                #text is: thread\tstackframe\tLOCAL\texpression
                temp_name = ""
                try:
                    thread_id, frame_id, scope, expression, trim, temp_name = text.split(
                        '\t', 5)
                except ValueError:
                    thread_id, frame_id, scope, expression, trim = text.split(
                        '\t', 4)
                int_cmd = InternalEvaluateExpression(
                    seq, thread_id, frame_id, expression,
                    cmd_id == CMD_EXEC_EXPRESSION,
                    int(trim) == 1, temp_name)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_CONSOLE_EXEC:
                #command to exec expression in console, in case expression is only partially valid 'False' is returned
                #text is: thread\tstackframe\tLOCAL\texpression

                thread_id, frame_id, scope, expression = text.split('\t', 3)

                int_cmd = InternalConsoleExec(seq, thread_id, frame_id,
                                              expression)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_PY_EXCEPTION:
                # Command which receives set of exceptions on which user wants to break the debugger
                # text is:
                #
                # break_on_uncaught;
                # break_on_caught;
                # skip_on_exceptions_thrown_in_same_context;
                # ignore_exceptions_thrown_in_lines_with_ignore_exception;
                # ignore_libraries;
                # TypeError;ImportError;zipimport.ZipImportError;
                #
                # i.e.: true;true;true;true;true;TypeError;ImportError;zipimport.ZipImportError;
                #
                # This API is optional and works 'in bulk' -- it's possible
                # to get finer-grained control with CMD_ADD_EXCEPTION_BREAK/CMD_REMOVE_EXCEPTION_BREAK
                # which allows setting caught/uncaught per exception.
                splitted = text.split(';')
                py_db.break_on_uncaught_exceptions = {}
                py_db.break_on_caught_exceptions = {}
                if len(splitted) >= 5:
                    if splitted[0] == 'true':
                        break_on_uncaught = True
                    else:
                        break_on_uncaught = False

                    if splitted[1] == 'true':
                        break_on_caught = True
                    else:
                        break_on_caught = False

                    if splitted[2] == 'true':
                        py_db.skip_on_exceptions_thrown_in_same_context = True
                    else:
                        py_db.skip_on_exceptions_thrown_in_same_context = False

                    if splitted[3] == 'true':
                        py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = True
                    else:
                        py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = False

                    if splitted[4] == 'true':
                        ignore_libraries = True
                    else:
                        ignore_libraries = False

                    for exception_type in splitted[5:]:
                        exception_type = exception_type.strip()
                        if not exception_type:
                            continue

                        exception_breakpoint = py_db.add_break_on_exception(
                            exception_type,
                            condition=None,
                            expression=None,
                            notify_on_handled_exceptions=break_on_caught,
                            notify_on_unhandled_exceptions=break_on_uncaught,
                            notify_on_first_raise_only=True,
                            ignore_libraries=ignore_libraries,
                        )

                    py_db.on_breakpoints_changed()

                else:
                    sys.stderr.write(
                        "Error when setting exception list. Received: %s\n" %
                        (text, ))

            elif cmd_id == CMD_GET_FILE_CONTENTS:

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    text = text.encode(file_system_encoding)

                if os.path.exists(text):
                    f = open(text, 'r')
                    try:
                        source = f.read()
                    finally:
                        f.close()
                    cmd = py_db.cmd_factory.make_get_file_contents(seq, source)

            elif cmd_id == CMD_SET_PROPERTY_TRACE:
                # Command which receives whether to trace property getter/setter/deleter
                # text is feature_state(true/false);disable_getter/disable_setter/disable_deleter
                if text != "":
                    splitted = text.split(';')
                    if len(splitted) >= 3:
                        if py_db.disable_property_trace is False and splitted[
                                0] == 'true':
                            # Replacing property by custom property only when the debugger starts
                            pydevd_traceproperty.replace_builtin_property()
                            py_db.disable_property_trace = True
                        # Enable/Disable tracing of the property getter
                        if splitted[1] == 'true':
                            py_db.disable_property_getter_trace = True
                        else:
                            py_db.disable_property_getter_trace = False
                        # Enable/Disable tracing of the property setter
                        if splitted[2] == 'true':
                            py_db.disable_property_setter_trace = True
                        else:
                            py_db.disable_property_setter_trace = False
                        # Enable/Disable tracing of the property deleter
                        if splitted[3] == 'true':
                            py_db.disable_property_deleter_trace = True
                        else:
                            py_db.disable_property_deleter_trace = False
                else:
                    # User hasn't configured any settings for property tracing
                    pass

            elif cmd_id == CMD_ADD_EXCEPTION_BREAK:
                # Note that this message has some idiosyncrasies...
                #
                # notify_on_handled_exceptions can be 0, 1 or 2
                # 0 means we should not stop on handled exceptions.
                # 1 means we should stop on handled exceptions showing it on all frames where the exception passes.
                # 2 means we should stop on handled exceptions but we should only notify about it once.
                #
                # To ignore_libraries properly, besides setting ignore_libraries to 1, the IDE_PROJECT_ROOTS environment
                # variable must be set (so, we'll ignore anything not below IDE_PROJECT_ROOTS) -- this is not ideal as
                # the environment variable may not be properly set if it didn't start from the debugger (we should
                # create a custom message for that).
                #
                # There are 2 global settings which can only be set in CMD_SET_PY_EXCEPTION. Namely:
                #
                # py_db.skip_on_exceptions_thrown_in_same_context
                # - If True, we should only show the exception in a caller, not where it was first raised.
                #
                # py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception
                # - If True exceptions thrown in lines with '@IgnoreException' will not be shown.

                condition = ""
                expression = ""
                if text.find('\t') != -1:
                    try:
                        exception, condition, expression, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text.split(
                            '\t', 5)
                    except:
                        exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text.split(
                            '\t', 3)
                else:
                    exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text, 0, 0, 0

                condition = condition.replace("@_@NEW_LINE_CHAR@_@",
                                              '\n').replace(
                                                  "@_@TAB_CHAR@_@",
                                                  '\t').strip()

                if condition is not None and (len(condition) == 0
                                              or condition == "None"):
                    condition = None

                expression = expression.replace("@_@NEW_LINE_CHAR@_@",
                                                '\n').replace(
                                                    "@_@TAB_CHAR@_@",
                                                    '\t').strip()

                if expression is not None and (len(expression) == 0
                                               or expression == "None"):
                    expression = None

                if exception.find('-') != -1:
                    breakpoint_type, exception = exception.split('-')
                else:
                    breakpoint_type = 'python'

                if breakpoint_type == 'python':
                    exception_breakpoint = py_db.add_break_on_exception(
                        exception,
                        condition=condition,
                        expression=expression,
                        notify_on_handled_exceptions=int(
                            notify_on_handled_exceptions) > 0,
                        notify_on_unhandled_exceptions=int(
                            notify_on_unhandled_exceptions) == 1,
                        notify_on_first_raise_only=int(
                            notify_on_handled_exceptions) == 2,
                        ignore_libraries=int(ignore_libraries) > 0)

                    if exception_breakpoint is not None:
                        py_db.on_breakpoints_changed()
                else:
                    supported_type = False
                    plugin = py_db.get_plugin_lazy_init()
                    if plugin is not None:
                        supported_type = plugin.add_breakpoint(
                            'add_exception_breakpoint', py_db, breakpoint_type,
                            exception)

                    if supported_type:
                        py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks(
                        )
                        py_db.on_breakpoints_changed()
                    else:
                        raise NameError(breakpoint_type)

            elif cmd_id == CMD_REMOVE_EXCEPTION_BREAK:
                exception = text
                if exception.find('-') != -1:
                    exception_type, exception = exception.split('-')
                else:
                    exception_type = 'python'

                if exception_type == 'python':
                    try:
                        cp = py_db.break_on_uncaught_exceptions.copy()
                        cp.pop(exception, None)
                        py_db.break_on_uncaught_exceptions = cp

                        cp = py_db.break_on_caught_exceptions.copy()
                        cp.pop(exception, None)
                        py_db.break_on_caught_exceptions = cp
                    except:
                        pydev_log.debug("Error while removing exception %s" %
                                        sys.exc_info()[0])
                else:
                    supported_type = False

                    # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
                    # anything from it anyways).
                    plugin = py_db.plugin
                    if plugin is not None:
                        supported_type = plugin.remove_exception_breakpoint(
                            py_db, exception_type, exception)

                    if supported_type:
                        py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks(
                        )
                    else:
                        raise NameError(exception_type)

                py_db.on_breakpoints_changed(removed=True)

            elif cmd_id == CMD_LOAD_SOURCE:
                path = text
                try:
                    if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                        path = path.encode(file_system_encoding)

                    path = pydevd_file_utils.norm_file_to_server(path)
                    f = open(path, 'r')
                    source = f.read()
                    cmd = py_db.cmd_factory.make_load_source_message(
                        seq, source)
                except:
                    cmd = py_db.cmd_factory.make_error_message(
                        seq, pydevd_tracing.get_exception_traceback_str())

            elif cmd_id == CMD_ADD_DJANGO_EXCEPTION_BREAK:
                exception = text
                plugin = py_db.get_plugin_lazy_init()
                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.on_breakpoints_changed()

            elif cmd_id == CMD_REMOVE_DJANGO_EXCEPTION_BREAK:
                exception = text

                # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
                # anything from it anyways).
                plugin = py_db.plugin
                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(
                    )
                py_db.on_breakpoints_changed(removed=True)

            elif cmd_id == CMD_EVALUATE_CONSOLE_EXPRESSION:
                # Command which takes care for the debug console communication
                if text != "":
                    thread_id, frame_id, console_command = text.split('\t', 2)
                    console_command, line = console_command.split('\t')

                    if console_command == 'EVALUATE':
                        int_cmd = InternalEvaluateConsoleExpression(
                            seq, thread_id, frame_id, line, buffer_output=True)

                    elif console_command == 'EVALUATE_UNBUFFERED':
                        int_cmd = InternalEvaluateConsoleExpression(
                            seq,
                            thread_id,
                            frame_id,
                            line,
                            buffer_output=False)

                    elif console_command == 'GET_COMPLETIONS':
                        int_cmd = InternalConsoleGetCompletions(
                            seq, thread_id, frame_id, line)

                    else:
                        raise ValueError('Unrecognized command: %s' %
                                         (console_command, ))

                    py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_RUN_CUSTOM_OPERATION:
                # Command which runs a custom operation
                if text != "":
                    try:
                        location, custom = text.split('||', 1)
                    except:
                        sys.stderr.write(
                            'Custom operation now needs a || separator. Found: %s\n'
                            % (text, ))
                        raise

                    thread_id, frame_id, scopeattrs = location.split('\t', 2)

                    if scopeattrs.find(
                            '\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    # : style: EXECFILE or EXEC
                    # : encoded_code_or_file: file to execute or code
                    # : fname: name of function to be executed in the resulting namespace
                    style, encoded_code_or_file, fnname = custom.split('\t', 3)
                    int_cmd = InternalRunCustomOperation(
                        seq, thread_id, frame_id, scope, attrs, style,
                        encoded_code_or_file, fnname)
                    py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_IGNORE_THROWN_EXCEPTION_AT:
                if text:
                    replace = 'REPLACE:'  # Not all 3.x versions support u'REPLACE:', so, doing workaround.
                    if not IS_PY3K:
                        replace = unicode(replace)

                    if text.startswith(replace):
                        text = text[8:]
                        py_db.filename_to_lines_where_exceptions_are_ignored.clear(
                        )

                    if text:
                        for line in text.split(
                                '||'
                        ):  # Can be bulk-created (one in each line)
                            filename, line_number = line.split('|')
                            if not IS_PY3K:
                                filename = filename.encode(
                                    file_system_encoding)

                            filename = pydevd_file_utils.norm_file_to_server(
                                filename)

                            if os.path.exists(filename):
                                lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored.get(
                                    filename)
                                if lines_ignored is None:
                                    lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored[
                                        filename] = {}
                                lines_ignored[int(line_number)] = 1
                            else:
                                sys.stderr.write(
                                    'pydev debugger: warning: trying to ignore exception thrown'
                                    ' on file that does not exist: %s (will have no effect)\n'
                                    % (filename, ))

            elif cmd_id == CMD_ENABLE_DONT_TRACE:
                if text:
                    true_str = 'true'  # Not all 3.x versions support u'str', so, doing workaround.
                    if not IS_PY3K:
                        true_str = unicode(true_str)

                    mode = text.strip() == true_str
                    pydevd_dont_trace.trace_filter(mode)

            elif cmd_id == CMD_PROCESS_CREATED_MSG_RECEIVED:
                original_seq = int(text)

                event = py_db.process_created_msg_received_events.pop(
                    original_seq, None)

                if event:
                    event.set()

            elif cmd_id == CMD_REDIRECT_OUTPUT:
                if text:
                    py_db.enable_output_redirection('STDOUT' in text, 'STDERR'
                                                    in text)

            elif cmd_id == CMD_GET_NEXT_STATEMENT_TARGETS:
                thread_id, frame_id = text.split('\t', 1)

                int_cmd = InternalGetNextStatementTargets(
                    seq, thread_id, frame_id)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_PROJECT_ROOTS:
                pydevd_utils.set_project_roots(text.split(u'\t'))

            elif cmd_id == CMD_THREAD_DUMP_TO_STDERR:
                pydevd_utils.dump_threads()

            elif cmd_id == CMD_STOP_ON_START:
                py_db.stop_on_start = text.strip() in ('True', 'true', '1')

            elif cmd_id == CMD_PYDEVD_JSON_CONFIG:
                # Expected to receive a json string as:
                # {
                #     'skip_suspend_on_breakpoint_exception': [<exception names where we should suspend>],
                #     'skip_print_breakpoint_exception': [<exception names where we should print>],
                #     'multi_threads_single_notification': bool,
                # }
                msg = json.loads(text.strip())
                if 'skip_suspend_on_breakpoint_exception' in msg:
                    py_db.skip_suspend_on_breakpoint_exception = tuple(
                        get_exception_class(x)
                        for x in msg['skip_suspend_on_breakpoint_exception'])

                if 'skip_print_breakpoint_exception' in msg:
                    py_db.skip_print_breakpoint_exception = tuple(
                        get_exception_class(x)
                        for x in msg['skip_print_breakpoint_exception'])

                if 'multi_threads_single_notification' in msg:
                    py_db.multi_threads_single_notification = msg[
                        'multi_threads_single_notification']

            elif cmd_id == CMD_GET_EXCEPTION_DETAILS:
                thread_id = text
                t = pydevd_find_thread_by_id(thread_id)
                frame = None
                if t and not getattr(t, 'pydev_do_not_trace', None):
                    additional_info = set_additional_thread_info(t)
                    frame = additional_info.get_topmost_frame(t)
                try:
                    cmd = py_db.cmd_factory.make_get_exception_details_message(
                        seq, thread_id, frame)
                finally:
                    frame = None
                    t = None

            elif cmd_id == CMD_GET_SMART_STEP_INTO_VARIANTS:
                thread_id, frame_id, start_line, end_line = text.split('\t', 3)
                int_cmd = InternalGetSmartStepIntoVariants(
                    seq, thread_id, frame_id, start_line, end_line)
                py_db.post_internal_command(int_cmd, thread_id)

            # Powerful DataViewer commands
            elif cmd_id == CMD_DATAVIEWER_ACTION:
                # format: thread_id frame_id name temp
                try:
                    thread_id, frame_id, var, action, args = text.split(
                        '\t', 4)
                    args = args.split('\t')

                    int_cmd = InternalDataViewerAction(seq, thread_id,
                                                       frame_id, var, action,
                                                       args)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            else:
                #I have no idea what this is all about
                cmd = py_db.cmd_factory.make_error_message(
                    seq, "unexpected command " + str(cmd_id))

            if cmd is not None:
                py_db.writer.add_command(cmd)
                del cmd

        except Exception:
            traceback.print_exc()
            try:
                from StringIO import StringIO
            except ImportError:
                from io import StringIO
            stream = StringIO()
            traceback.print_exc(file=stream)
            cmd = py_db.cmd_factory.make_error_message(
                seq,
                "Unexpected exception in process_net_command.\nInitial params: %s. Exception: %s"
                % (((cmd_id, seq, text), stream.getvalue())))

            py_db.writer.add_command(cmd)
    finally:
        py_db._main_lock.release()
def create_source_reference_for_frame_id(frame_id, original_filename):
    source_reference = _next_source_reference()
    pydev_log.debug('Created frame id source reference: %s for frame id: %s (%s)', source_reference, frame_id, original_filename)
    _source_reference_to_frame_id[source_reference] = frame_id
    return source_reference
def log_debug(msg):
    from _pydev_bundle import pydev_log
    pydev_log.debug(msg)
Exemple #50
0
    def should_stop_on_exception(self, frame, event, arg):
        # ENDIF

        # main_debugger, _filename, info, _thread = self._args
        main_debugger = self._args[0]
        info = self._args[2]
        should_stop = False

        # STATE_SUSPEND = 2
        if info.pydev_state != 2:  # and breakpoint is not None:
            exception, value, trace = arg

            if trace is not None and hasattr(trace, 'tb_next'):
                # on jython trace is None on the first event and it may not have a tb_next.

                should_stop = False
                exception_breakpoint = None
                try:
                    if main_debugger.plugin is not None:
                        result = main_debugger.plugin.exception_break(
                            main_debugger, self, frame, self._args, arg)
                        if result:
                            should_stop, frame = result
                except:
                    pydev_log.exception()

                if not should_stop:
                    # It was not handled by any plugin, lets check exception breakpoints.
                    exception_breakpoint = main_debugger.get_exception_breakpoint(
                        exception, main_debugger.break_on_caught_exceptions)

                    if exception_breakpoint is not None:
                        if exception is SystemExit and main_debugger.ignore_system_exit_code(
                                value):
                            return False, frame

                        if exception in (GeneratorExit, StopIteration):
                            # These exceptions are control-flow related (they work as a generator
                            # pause), so, we shouldn't stop on them.
                            return False, frame

                        if exception_breakpoint.condition is not None:
                            eval_result = main_debugger.handle_breakpoint_condition(
                                info, exception_breakpoint, frame)
                            if not eval_result:
                                return False, frame

                        if main_debugger.exclude_exception_by_filter(
                                exception_breakpoint, trace, False):
                            pydev_log.debug(
                                "Ignore exception %s in library %s -- (%s)" %
                                (exception, frame.f_code.co_filename,
                                 frame.f_code.co_name))
                            return False, frame

                        if ignore_exception_trace(trace):
                            return False, frame

                        was_just_raised = just_raised(trace)
                        if was_just_raised:

                            if main_debugger.skip_on_exceptions_thrown_in_same_context:
                                # Option: Don't break if an exception is caught in the same function from which it is thrown
                                return False, frame

                        if exception_breakpoint.notify_on_first_raise_only:
                            if main_debugger.skip_on_exceptions_thrown_in_same_context:
                                # In this case we never stop if it was just raised, so, to know if it was the first we
                                # need to check if we're in the 2nd method.
                                if not was_just_raised and not just_raised(
                                        trace.tb_next):
                                    return False, frame  # I.e.: we stop only when we're at the caller of a method that throws an exception

                            else:
                                if not was_just_raised:
                                    return False, frame  # I.e.: we stop only when it was just raised

                        # If it got here we should stop.
                        should_stop = True
                        try:
                            info.pydev_message = exception_breakpoint.qname
                        except:
                            info.pydev_message = exception_breakpoint.qname.encode(
                                'utf-8')

                if should_stop:
                    # Always add exception to frame (must remove later after we proceed).
                    add_exception_to_frame(frame, (exception, value, trace))

                    if exception_breakpoint is not None and exception_breakpoint.expression is not None:
                        main_debugger.handle_breakpoint_expression(
                            exception_breakpoint, info, frame)

        return should_stop, frame
Exemple #51
0
    def add_breakpoint(
            self, py_db, filename, breakpoint_type, breakpoint_id, line, condition, func_name, expression, suspend_policy, hit_condition, is_logpoint):
        '''
        :param str filename:
            Note: must be already translated for the server.

        :param str breakpoint_type:
            One of: 'python-line', 'django-line', 'jinja2-line'.

        :param int breakpoint_id:

        :param int line:

        :param condition:
            Either None or the condition to activate the breakpoint.

        :param str func_name:
            If "None" (str), may hit in any context.
            Empty string will hit only top level.
            Any other value must match the scope of the method to be matched.

        :param str expression:
            None or the expression to be evaluated.

        :param suspend_policy:
            Either "NONE" (to suspend only the current thread when the breakpoint is hit) or
            "ALL" (to suspend all threads when a breakpoint is hit).

        :param str hit_condition:
            An expression where `@HIT@` will be replaced by the number of hits.
            i.e.: `@HIT@ == x` or `@HIT@ >= x`

        :param bool is_logpoint:
            If True and an expression is passed, pydevd will create an io message command with the
            result of the evaluation.

        :return int:
            :see: ADD_BREAKPOINT_NO_ERROR = 0
            :see: ADD_BREAKPOINT_FILE_NOT_FOUND = 1
            :see: ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS = 2
        '''
        assert filename.__class__ == str  # i.e.: bytes on py2 and str on py3
        assert func_name.__class__ == str  # i.e.: bytes on py2 and str on py3

        if not pydevd_file_utils.exists(filename):
            return self.ADD_BREAKPOINT_FILE_NOT_FOUND

        error_code = self.ADD_BREAKPOINT_NO_ERROR
        if (
                py_db.is_files_filter_enabled and
                not py_db.get_require_module_for_filters() and
                py_db.apply_files_filter(self._DummyFrame(filename), filename, False)
            ):
            # Note that if `get_require_module_for_filters()` returns False, we don't do this check.
            # This is because we don't have the module name given a file at this point (in
            # runtime it's gotten from the frame.f_globals).
            # An option could be calculate it based on the filename and current sys.path,
            # but on some occasions that may be wrong (for instance with `__main__` or if
            # the user dynamically changes the PYTHONPATH).

            # Note: depending on the use-case, filters may be changed, so, keep on going and add the
            # breakpoint even with the error code.
            error_code = self.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS

        if breakpoint_type == 'python-line':
            added_breakpoint = LineBreakpoint(line, condition, func_name, expression, suspend_policy, hit_condition=hit_condition, is_logpoint=is_logpoint)
            breakpoints = py_db.breakpoints
            file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
            supported_type = True

        else:
            result = None
            plugin = py_db.get_plugin_lazy_init()
            if plugin is not None:
                result = plugin.add_breakpoint('add_line_breakpoint', py_db, breakpoint_type, filename, line, condition, expression, func_name, hit_condition=hit_condition, is_logpoint=is_logpoint)
            if result is not None:
                supported_type = True
                added_breakpoint, breakpoints = result
                file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
            else:
                supported_type = False

        if not supported_type:
            raise NameError(breakpoint_type)

        if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
            pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n', filename, line, func_name)

        if filename in file_to_id_to_breakpoint:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename]
        else:
            id_to_pybreakpoint = file_to_id_to_breakpoint[filename] = {}

        id_to_pybreakpoint[breakpoint_id] = added_breakpoint
        py_db.consolidate_breakpoints(filename, id_to_pybreakpoint, breakpoints)
        if py_db.plugin is not None:
            py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

        py_db.on_breakpoints_changed()
        return error_code
    def should_stop_on_exception(self, frame, event, arg):
    # ENDIF

        # main_debugger, _filename, info, _thread = self._args
        main_debugger = self._args[0]
        info = self._args[2]
        flag = False

        # STATE_SUSPEND = 2
        if info.pydev_state != 2:  #and breakpoint is not None:
            exception, value, trace = arg

            if trace is not None: #on jython trace is None on the first event
                exception_breakpoint = get_exception_breakpoint(
                    exception, main_debugger.break_on_caught_exceptions)

                if exception_breakpoint is not None:
                    add_exception_to_frame(frame, (exception, value, trace))
                    if exception_breakpoint.condition is not None:
                        eval_result = handle_breakpoint_condition(main_debugger, info, exception_breakpoint, frame)
                        if not eval_result:
                            return False, frame

                    if exception_breakpoint.ignore_libraries:
                        if exception_breakpoint.notify_on_first_raise_only:
                            if main_debugger.first_appearance_in_scope(trace):
                                add_exception_to_frame(frame, (exception, value, trace))
                                try:
                                    info.pydev_message = exception_breakpoint.qname
                                except:
                                    info.pydev_message = exception_breakpoint.qname.encode('utf-8')
                                flag = True
                            else:
                                pydev_log.debug("Ignore exception %s in library %s" % (exception, frame.f_code.co_filename))
                                flag = False
                    else:
                        if not exception_breakpoint.notify_on_first_raise_only or just_raised(trace):
                            add_exception_to_frame(frame, (exception, value, trace))
                            try:
                                info.pydev_message = exception_breakpoint.qname
                            except:
                                info.pydev_message = exception_breakpoint.qname.encode('utf-8')
                            flag = True
                        else:
                            flag = False
                else:
                    try:
                        if main_debugger.plugin is not None:
                            result = main_debugger.plugin.exception_break(main_debugger, self, frame, self._args, arg)
                            if result:
                                flag, frame = result
                    except:
                        flag = False

                if flag:
                    if exception_breakpoint is not None and exception_breakpoint.expression is not None:
                        handle_breakpoint_expression(exception_breakpoint, info, frame)
                else:
                    remove_exception_from_frame(frame)

        return flag, frame
Exemple #53
0
    def should_stop_on_exception(self, frame, event, arg):
    # ENDIF

        # main_debugger, _filename, info, _thread = self._args
        main_debugger = self._args[0]
        info = self._args[2]
        should_stop = False

        # STATE_SUSPEND = 2
        if info.pydev_state != 2:  # and breakpoint is not None:
            exception, value, trace = arg

            if trace is not None and hasattr(trace, 'tb_next'):
                # on jython trace is None on the first event and it may not have a tb_next.

                exception_breakpoint = get_exception_breakpoint(
                    exception, main_debugger.break_on_caught_exceptions)

                if exception_breakpoint is not None:
                    if exception_breakpoint.condition is not None:
                        eval_result = handle_breakpoint_condition(main_debugger, info, exception_breakpoint, frame)
                        if not eval_result:
                            return False, frame

                    if exception_breakpoint.ignore_libraries:
                        if not main_debugger.is_exception_trace_in_project_scope(trace):
                            pydev_log.debug("Ignore exception %s in library %s -- (%s)" % (exception, frame.f_code.co_filename, frame.f_code.co_name))
                            return False, frame

                    if ignore_exception_trace(trace):
                        return False, frame

                    was_just_raised = just_raised(trace)
                    if was_just_raised:

                        if main_debugger.skip_on_exceptions_thrown_in_same_context:
                            # Option: Don't break if an exception is caught in the same function from which it is thrown
                            return False, frame

                    if exception_breakpoint.notify_on_first_raise_only:
                        if main_debugger.skip_on_exceptions_thrown_in_same_context:
                            # In this case we never stop if it was just raised, so, to know if it was the first we
                            # need to check if we're in the 2nd method.
                            if not was_just_raised and not just_raised(trace.tb_next):
                                return False, frame  # I.e.: we stop only when we're at the caller of a method that throws an exception

                        else:
                            if not was_just_raised:
                                return False, frame  # I.e.: we stop only when it was just raised

                    # If it got here we should stop.
                    should_stop = True
                    try:
                        info.pydev_message = exception_breakpoint.qname
                    except:
                        info.pydev_message = exception_breakpoint.qname.encode('utf-8')

                    # Always add exception to frame (must remove later after we proceed).
                    add_exception_to_frame(frame, (exception, value, trace))

                else:
                    # No regular exception breakpoint, let's see if some plugin handles it.
                    try:
                        if main_debugger.plugin is not None:
                            result = main_debugger.plugin.exception_break(main_debugger, self, frame, self._args, arg)
                            if result:
                                should_stop, frame = result
                    except:
                        should_stop = False

                if should_stop:
                    if exception_breakpoint is not None and exception_breakpoint.expression is not None:
                        handle_breakpoint_expression(exception_breakpoint, info, frame)

        return should_stop, frame
def process_net_command(py_db, cmd_id, seq, text):
    '''Processes a command received from the Java side

    @param cmd_id: the id of the command
    @param seq: the sequence of the command
    @param text: the text received in the command

    @note: this method is run as a big switch... after doing some tests, it's not clear whether changing it for
    a dict id --> function call will have better performance result. A simple test with xrange(10000000) showed
    that the gains from having a fast access to what should be executed are lost because of the function call in
    a way that if we had 10 elements in the switch the if..elif are better -- but growing the number of choices
    makes the solution with the dispatch look better -- so, if this gets more than 20-25 choices at some time,
    it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before
    probably will give better performance).
    '''
    # print(ID_TO_MEANING[str(cmd_id)], repr(text))

    py_db._main_lock.acquire()
    try:
        try:
            cmd = None
            if cmd_id == CMD_RUN:
                py_db.ready_to_run = True

            elif cmd_id == CMD_SET_PROTOCOL:
                expected = (NetCommand.HTTP_PROTOCOL, NetCommand.QUOTED_LINE_PROTOCOL)
                text = text.strip()
                assert text.strip() in expected, 'Protocol (%s) should be one of: %s' % (
                    text, expected)

                NetCommand.protocol = text
                cmd = py_db.cmd_factory.make_protocol_set_message(seq)

            elif cmd_id == CMD_VERSION:
                # response is version number
                # ide_os should be 'WINDOWS' or 'UNIX'.

                # Default based on server process (although ideally the IDE should
                # provide it).
                if IS_WINDOWS:
                    ide_os = 'WINDOWS'
                else:
                    ide_os = 'UNIX'

                # Breakpoints can be grouped by 'LINE' or by 'ID'.
                breakpoints_by = 'LINE'

                splitted = text.split('\t')
                if len(splitted) == 1:
                    _local_version = splitted

                elif len(splitted) == 2:
                    _local_version, ide_os = splitted

                elif len(splitted) == 3:
                    _local_version, ide_os, breakpoints_by = splitted

                if breakpoints_by == 'ID':
                    py_db._set_breakpoints_with_id = True
                else:
                    py_db._set_breakpoints_with_id = False

                pydevd_file_utils.set_ide_os(ide_os)

                cmd = py_db.cmd_factory.make_version_message(seq)

            elif cmd_id == CMD_LIST_THREADS:
                # response is a list of threads
                cmd = py_db.cmd_factory.make_list_threads_message(seq)

            elif cmd_id == CMD_GET_THREAD_STACK:
                # Receives a thread_id and a given timeout, which is the time we should
                # wait to the provide the stack if a given thread is still not suspended.
                if '\t' in text:
                    thread_id, timeout = text.split('\t')
                    timeout = float(timeout)
                else:
                    thread_id = text
                    timeout = .5  # Default timeout is .5 seconds

                # If it's already suspended, get it right away.
                internal_get_thread_stack = InternalGetThreadStack(seq, thread_id, py_db, set_additional_thread_info, timeout=timeout)
                if internal_get_thread_stack.can_be_executed_by(get_current_thread_id(threading.current_thread())):
                    internal_get_thread_stack.do_it(py_db)
                else:
                    py_db.post_internal_command(internal_get_thread_stack, '*')

            elif cmd_id == CMD_THREAD_SUSPEND:
                # Yes, thread suspend is done at this point, not through an internal command.
                threads = []
                suspend_all = text.strip() == '*'
                if suspend_all:
                    threads = pydevd_utils.get_non_pydevd_threads()
                
                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't suspend tasklet: %s\n" % (text,))
                    
                else:
                    threads = [pydevd_find_thread_by_id(text)]
                    
                for t in threads:
                    if t is None:
                        continue
                    py_db.set_suspend(
                        t,
                        CMD_THREAD_SUSPEND,
                        suspend_other_threads=suspend_all,
                        is_pause=True,
                    )
                    # Break here (even if it's suspend all) as py_db.set_suspend will
                    # take care of suspending other threads.
                    break

            elif cmd_id == CMD_THREAD_RUN:
                threads = []
                if text.strip() == '*':
                    threads = pydevd_utils.get_non_pydevd_threads()
                
                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't make tasklet run: %s\n" % (text,))
                    
                else:
                    threads = [pydevd_find_thread_by_id(text)]

                for t in threads:
                    if t is None:
                        continue
                    additional_info = set_additional_thread_info(t)
                    additional_info.pydev_step_cmd = -1
                    additional_info.pydev_step_stop = None
                    additional_info.pydev_state = STATE_RUN

            elif cmd_id == CMD_STEP_INTO or cmd_id == CMD_STEP_OVER or cmd_id == CMD_STEP_RETURN or \
                    cmd_id == CMD_STEP_INTO_MY_CODE:
                # we received some command to make a single step
                t = pydevd_find_thread_by_id(text)
                if t:
                    thread_id = get_thread_id(t)
                    int_cmd = InternalStepThread(thread_id, cmd_id)
                    py_db.post_internal_command(int_cmd, thread_id)

                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't make tasklet step command: %s\n" % (text,))


            elif cmd_id == CMD_RUN_TO_LINE or cmd_id == CMD_SET_NEXT_STATEMENT or cmd_id == CMD_SMART_STEP_INTO:
                # we received some command to make a single step
                thread_id, line, func_name = text.split('\t', 2)
                t = pydevd_find_thread_by_id(thread_id)
                if t:
                    int_cmd = InternalSetNextStatementThread(thread_id, cmd_id, line, func_name)
                    py_db.post_internal_command(int_cmd, thread_id)
                elif thread_id.startswith('__frame__:'):
                    sys.stderr.write("Can't set next statement in tasklet: %s\n" % (thread_id,))


            elif cmd_id == CMD_RELOAD_CODE:
                # we received some command to make a reload of a module
                module_name = text.strip()

                thread_id = '*'  # Any thread
                # Note: not going for the main thread because in this case it'd only do the load
                # when we stopped on a breakpoint.
                int_cmd = ReloadCodeCommand(module_name, thread_id)
                py_db.post_internal_command(int_cmd, thread_id)


            elif cmd_id == CMD_CHANGE_VARIABLE:
                # the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change
                try:
                    thread_id, frame_id, scope, attr_and_value = text.split('\t', 3)

                    tab_index = attr_and_value.rindex('\t')
                    attr = attr_and_value[0:tab_index].replace('\t', '.')
                    value = attr_and_value[tab_index + 1:]
                    int_cmd = InternalChangeVariable(seq, thread_id, frame_id, scope, attr, value)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_VARIABLE:
                # we received some command to get a variable
                # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes*
                try:
                    thread_id, frame_id, scopeattrs = text.split('\t', 2)

                    if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    int_cmd = InternalGetVariable(seq, thread_id, frame_id, scope, attrs)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_ARRAY:
                # we received some command to get an array variable
                # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tname\ttemp\troffs\tcoffs\trows\tcols\tformat
                try:
                    roffset, coffset, rows, cols, format, thread_id, frame_id, scopeattrs  = text.split('\t', 7)

                    if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    int_cmd = InternalGetArray(seq, roffset, coffset, rows, cols, format, thread_id, frame_id, scope, attrs)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_SHOW_RETURN_VALUES:
                try:
                    show_return_values = text.split('\t')[1]
                    if int(show_return_values) == 1:
                        py_db.show_return_values = True
                    else:
                        if py_db.show_return_values:
                            # We should remove saved return values
                            py_db.remove_return_values_flag = True
                        py_db.show_return_values = False
                    pydev_log.debug("Show return values: %s\n" % py_db.show_return_values)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_LOAD_FULL_VALUE:
                try:
                    thread_id, frame_id, scopeattrs = text.split('\t', 2)
                    vars = scopeattrs.split(NEXT_VALUE_SEPARATOR)

                    int_cmd = InternalLoadFullValue(seq, thread_id, frame_id, vars)
                    py_db.post_internal_command(int_cmd, thread_id)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_COMPLETIONS:
                # we received some command to get a variable
                # the text is: thread_id\tframe_id\tactivation token
                try:
                    thread_id, frame_id, scope, act_tok = text.split('\t', 3)

                    int_cmd = InternalGetCompletions(seq, thread_id, frame_id, act_tok)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()
            elif cmd_id == CMD_GET_DESCRIPTION:
                try:

                    thread_id, frame_id, expression = text.split('\t', 2)
                    int_cmd = InternalGetDescription(seq, thread_id, frame_id, expression)
                    py_db.post_internal_command(int_cmd, thread_id)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_FRAME:
                thread_id, frame_id, scope = text.split('\t', 2)

                int_cmd = InternalGetFrame(seq, thread_id, frame_id)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_BREAK:
                # func name: 'None': match anything. Empty: match global, specified: only method context.
                # command to add some breakpoint.
                # text is file\tline. Add to breakpoints dictionary
                suspend_policy = "NONE" # Can be 'NONE' or 'ALL'
                is_logpoint = False
                hit_condition = None
                if py_db._set_breakpoints_with_id:
                    try:
                        try:
                            breakpoint_id, type, file, line, func_name, condition, expression, hit_condition, is_logpoint, suspend_policy = text.split('\t', 9)
                        except ValueError: # not enough values to unpack
                            # No suspend_policy passed (use default).
                            breakpoint_id, type, file, line, func_name, condition, expression, hit_condition, is_logpoint = text.split('\t', 8)
                        is_logpoint = is_logpoint == 'True'
                    except ValueError: # not enough values to unpack
                        breakpoint_id, type, file, line, func_name, condition, expression = text.split('\t', 6)

                    breakpoint_id = int(breakpoint_id)
                    line = int(line)

                    # We must restore new lines and tabs as done in
                    # AbstractDebugTarget.breakpointAdded
                    condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').\
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                    expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n').\
                        replace("@_@TAB_CHAR@_@", '\t').strip()
                else:
                    # Note: this else should be removed after PyCharm migrates to setting
                    # breakpoints by id (and ideally also provides func_name).
                    type, file, line, func_name, suspend_policy, condition, expression = text.split('\t', 6)
                    # If we don't have an id given for each breakpoint, consider
                    # the id to be the line.
                    breakpoint_id = line = int(line)

                    condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                    expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    file = file.encode(file_system_encoding)

                file = pydevd_file_utils.norm_file_to_server(file)

                if not pydevd_file_utils.exists(file):
                    sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\
                        ' to file that does not exist: %s (will have no effect)\n' % (file,))
                    sys.stderr.flush()


                if condition is not None and (len(condition) <= 0 or condition == "None"):
                    condition = None

                if expression is not None and (len(expression) <= 0 or expression == "None"):
                    expression = None

                if hit_condition is not None and (len(hit_condition) <= 0 or hit_condition == "None"):
                    hit_condition = None

                if type == 'python-line':
                    breakpoint = LineBreakpoint(line, condition, func_name, expression, suspend_policy, hit_condition=hit_condition, is_logpoint=is_logpoint)
                    breakpoints = py_db.breakpoints
                    file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
                    supported_type = True
                else:
                    result = None
                    plugin = py_db.get_plugin_lazy_init()
                    if plugin is not None:
                        result = plugin.add_breakpoint('add_line_breakpoint', py_db, type, file, line, condition, expression, func_name, hit_condition=hit_condition, is_logpoint=is_logpoint)
                    if result is not None:
                        supported_type = True
                        breakpoint, breakpoints = result
                        file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
                    else:
                        supported_type = False

                if not supported_type:
                    raise NameError(type)

                if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
                    pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name.encode('utf-8')))
                    sys.stderr.flush()

                if file in file_to_id_to_breakpoint:
                    id_to_pybreakpoint = file_to_id_to_breakpoint[file]
                else:
                    id_to_pybreakpoint = file_to_id_to_breakpoint[file] = {}

                id_to_pybreakpoint[breakpoint_id] = breakpoint
                py_db.consolidate_breakpoints(file, id_to_pybreakpoint, breakpoints)
                if py_db.plugin is not None:
                    py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

                py_db.on_breakpoints_changed()

            elif cmd_id == CMD_REMOVE_BREAK:
                #command to remove some breakpoint
                #text is type\file\tid. Remove from breakpoints dictionary
                breakpoint_type, file, breakpoint_id = text.split('\t', 2)

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    file = file.encode(file_system_encoding)

                file = pydevd_file_utils.norm_file_to_server(file)

                try:
                    breakpoint_id = int(breakpoint_id)
                except ValueError:
                    pydev_log.error('Error removing breakpoint. Expected breakpoint_id to be an int. Found: %s' % (breakpoint_id,))

                else:
                    file_to_id_to_breakpoint = None
                    if breakpoint_type == 'python-line':
                        breakpoints = py_db.breakpoints
                        file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
                    elif py_db.get_plugin_lazy_init() is not None:
                        result = py_db.plugin.get_breakpoints(py_db, breakpoint_type)
                        if result is not None:
                            file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
                            breakpoints = result

                    if file_to_id_to_breakpoint is None:
                        pydev_log.error('Error removing breakpoint. Cant handle breakpoint of type %s' % breakpoint_type)
                    else:
                        try:
                            id_to_pybreakpoint = file_to_id_to_breakpoint.get(file, {})
                            if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
                                existing = id_to_pybreakpoint[breakpoint_id]
                                sys.stderr.write('Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n' % (
                                    file, existing.line, existing.func_name.encode('utf-8'), breakpoint_id))

                            del id_to_pybreakpoint[breakpoint_id]
                            py_db.consolidate_breakpoints(file, id_to_pybreakpoint, breakpoints)
                            if py_db.plugin is not None:
                                py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

                        except KeyError:
                            pydev_log.error("Error removing breakpoint: Breakpoint id not found: %s id: %s. Available ids: %s\n" % (
                                file, breakpoint_id, dict_keys(id_to_pybreakpoint)))

                py_db.on_breakpoints_changed(removed=True)

            elif cmd_id == CMD_EVALUATE_EXPRESSION or cmd_id == CMD_EXEC_EXPRESSION:
                #command to evaluate the given expression
                #text is: thread\tstackframe\tLOCAL\texpression
                temp_name = ""
                try:
                    thread_id, frame_id, scope, expression, trim, temp_name = text.split('\t', 5)
                except ValueError:
                    thread_id, frame_id, scope, expression, trim = text.split('\t', 4)
                int_cmd = InternalEvaluateExpression(seq, thread_id, frame_id, expression,
                    cmd_id == CMD_EXEC_EXPRESSION, int(trim) == 1, temp_name)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_CONSOLE_EXEC:
                #command to exec expression in console, in case expression is only partially valid 'False' is returned
                #text is: thread\tstackframe\tLOCAL\texpression

                thread_id, frame_id, scope, expression = text.split('\t', 3)

                int_cmd = InternalConsoleExec(seq, thread_id, frame_id, expression)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_PY_EXCEPTION:
                # Command which receives set of exceptions on which user wants to break the debugger
                # text is:
                #
                # break_on_uncaught;
                # break_on_caught;
                # skip_on_exceptions_thrown_in_same_context;
                # ignore_exceptions_thrown_in_lines_with_ignore_exception;
                # ignore_libraries;
                # TypeError;ImportError;zipimport.ZipImportError;
                #
                # i.e.: true;true;true;true;true;TypeError;ImportError;zipimport.ZipImportError;
                #
                # This API is optional and works 'in bulk' -- it's possible
                # to get finer-grained control with CMD_ADD_EXCEPTION_BREAK/CMD_REMOVE_EXCEPTION_BREAK
                # which allows setting caught/uncaught per exception.
                splitted = text.split(';')
                py_db.break_on_uncaught_exceptions = {}
                py_db.break_on_caught_exceptions = {}
                if len(splitted) >= 5:
                    if splitted[0] == 'true':
                        break_on_uncaught = True
                    else:
                        break_on_uncaught = False

                    if splitted[1] == 'true':
                        break_on_caught = True
                    else:
                        break_on_caught = False

                    if splitted[2] == 'true':
                        py_db.skip_on_exceptions_thrown_in_same_context = True
                    else:
                        py_db.skip_on_exceptions_thrown_in_same_context = False

                    if splitted[3] == 'true':
                        py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = True
                    else:
                        py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = False

                    if splitted[4] == 'true':
                        ignore_libraries = True
                    else:
                        ignore_libraries = False

                    for exception_type in splitted[5:]:
                        exception_type = exception_type.strip()
                        if not exception_type:
                            continue

                        exception_breakpoint = py_db.add_break_on_exception(
                            exception_type,
                            condition=None,
                            expression=None,
                            notify_on_handled_exceptions=break_on_caught,
                            notify_on_unhandled_exceptions=break_on_uncaught,
                            notify_on_first_raise_only=True,
                            ignore_libraries=ignore_libraries,
                        )

                    py_db.on_breakpoints_changed()

                else:
                    sys.stderr.write("Error when setting exception list. Received: %s\n" % (text,))

            elif cmd_id == CMD_GET_FILE_CONTENTS:

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    text = text.encode(file_system_encoding)

                if os.path.exists(text):
                    f = open(text, 'r')
                    try:
                        source = f.read()
                    finally:
                        f.close()
                    cmd = py_db.cmd_factory.make_get_file_contents(seq, source)

            elif cmd_id == CMD_SET_PROPERTY_TRACE:
                # Command which receives whether to trace property getter/setter/deleter
                # text is feature_state(true/false);disable_getter/disable_setter/disable_deleter
                if text != "":
                    splitted = text.split(';')
                    if len(splitted) >= 3:
                        if py_db.disable_property_trace is False and splitted[0] == 'true':
                            # Replacing property by custom property only when the debugger starts
                            pydevd_traceproperty.replace_builtin_property()
                            py_db.disable_property_trace = True
                        # Enable/Disable tracing of the property getter
                        if splitted[1] == 'true':
                            py_db.disable_property_getter_trace = True
                        else:
                            py_db.disable_property_getter_trace = False
                        # Enable/Disable tracing of the property setter
                        if splitted[2] == 'true':
                            py_db.disable_property_setter_trace = True
                        else:
                            py_db.disable_property_setter_trace = False
                        # Enable/Disable tracing of the property deleter
                        if splitted[3] == 'true':
                            py_db.disable_property_deleter_trace = True
                        else:
                            py_db.disable_property_deleter_trace = False
                else:
                    # User hasn't configured any settings for property tracing
                    pass

            elif cmd_id == CMD_ADD_EXCEPTION_BREAK:
                # Note that this message has some idiosyncrasies...
                #
                # notify_on_handled_exceptions can be 0, 1 or 2
                # 0 means we should not stop on handled exceptions.
                # 1 means we should stop on handled exceptions showing it on all frames where the exception passes.
                # 2 means we should stop on handled exceptions but we should only notify about it once.
                #
                # To ignore_libraries properly, besides setting ignore_libraries to 1, the IDE_PROJECT_ROOTS environment
                # variable must be set (so, we'll ignore anything not below IDE_PROJECT_ROOTS) -- this is not ideal as
                # the environment variable may not be properly set if it didn't start from the debugger (we should
                # create a custom message for that).
                #
                # There are 2 global settings which can only be set in CMD_SET_PY_EXCEPTION. Namely:
                #
                # py_db.skip_on_exceptions_thrown_in_same_context
                # - If True, we should only show the exception in a caller, not where it was first raised.
                #
                # py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception
                # - If True exceptions thrown in lines with '@IgnoreException' will not be shown.

                condition = ""
                expression = ""
                if text.find('\t') != -1:
                    try:
                        exception, condition, expression, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text.split('\t', 5)
                    except:
                        exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text.split('\t', 3)
                else:
                    exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text, 0, 0, 0

                condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').replace("@_@TAB_CHAR@_@", '\t').strip()

                if condition is not None and (len(condition) == 0 or condition == "None"):
                    condition = None

                expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n').replace("@_@TAB_CHAR@_@", '\t').strip()

                if expression is not None and (len(expression) == 0 or expression == "None"):
                    expression = None

                if exception.find('-') != -1:
                    breakpoint_type, exception = exception.split('-')
                else:
                    breakpoint_type = 'python'

                if breakpoint_type == 'python':
                    exception_breakpoint = py_db.add_break_on_exception(
                        exception,
                        condition=condition,
                        expression=expression,
                        notify_on_handled_exceptions=int(notify_on_handled_exceptions) > 0,
                        notify_on_unhandled_exceptions=int(notify_on_unhandled_exceptions) == 1,
                        notify_on_first_raise_only=int(notify_on_handled_exceptions) == 2,
                        ignore_libraries=int(ignore_libraries) > 0
                    )

                    if exception_breakpoint is not None:
                        py_db.on_breakpoints_changed()
                else:
                    supported_type = False
                    plugin = py_db.get_plugin_lazy_init()
                    if plugin is not None:
                        supported_type = plugin.add_breakpoint('add_exception_breakpoint', py_db, breakpoint_type, exception)

                    if supported_type:
                        py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
                        py_db.on_breakpoints_changed()
                    else:
                        raise NameError(breakpoint_type)



            elif cmd_id == CMD_REMOVE_EXCEPTION_BREAK:
                exception = text
                if exception.find('-') != -1:
                    exception_type, exception = exception.split('-')
                else:
                    exception_type = 'python'

                if exception_type == 'python':
                    try:
                        cp = py_db.break_on_uncaught_exceptions.copy()
                        cp.pop(exception, None)
                        py_db.break_on_uncaught_exceptions = cp

                        cp = py_db.break_on_caught_exceptions.copy()
                        cp.pop(exception, None)
                        py_db.break_on_caught_exceptions = cp
                    except:
                        pydev_log.debug("Error while removing exception %s"%sys.exc_info()[0])
                else:
                    supported_type = False

                    # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
                    # anything from it anyways).
                    plugin = py_db.plugin
                    if plugin is not None:
                        supported_type = plugin.remove_exception_breakpoint(py_db, exception_type, exception)

                    if supported_type:
                        py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
                    else:
                        raise NameError(exception_type)

                py_db.on_breakpoints_changed(remove=True)

            elif cmd_id == CMD_LOAD_SOURCE:
                path = text
                try:
                    if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                        path = path.encode(file_system_encoding)

                    path = pydevd_file_utils.norm_file_to_server(path)
                    f = open(path, 'r')
                    source = f.read()
                    cmd = py_db.cmd_factory.make_load_source_message(seq, source)
                except:
                    cmd = py_db.cmd_factory.make_error_message(seq, pydevd_tracing.get_exception_traceback_str())

            elif cmd_id == CMD_ADD_DJANGO_EXCEPTION_BREAK:
                exception = text
                plugin = py_db.get_plugin_lazy_init()
                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.on_breakpoints_changed()

            elif cmd_id == CMD_REMOVE_DJANGO_EXCEPTION_BREAK:
                exception = text

                # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
                # anything from it anyways).
                plugin = py_db.plugin
                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()
                py_db.on_breakpoints_changed(removed=True)

            elif cmd_id == CMD_EVALUATE_CONSOLE_EXPRESSION:
                # Command which takes care for the debug console communication
                if text != "":
                    thread_id, frame_id, console_command = text.split('\t', 2)
                    console_command, line = console_command.split('\t')

                    if console_command == 'EVALUATE':
                        int_cmd = InternalEvaluateConsoleExpression(
                            seq, thread_id, frame_id, line, buffer_output=True)

                    elif console_command == 'EVALUATE_UNBUFFERED':
                        int_cmd = InternalEvaluateConsoleExpression(
                            seq, thread_id, frame_id, line, buffer_output=False)

                    elif console_command == 'GET_COMPLETIONS':
                        int_cmd = InternalConsoleGetCompletions(seq, thread_id, frame_id, line)

                    else:
                        raise ValueError('Unrecognized command: %s' % (console_command,))

                    py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_RUN_CUSTOM_OPERATION:
                # Command which runs a custom operation
                if text != "":
                    try:
                        location, custom = text.split('||', 1)
                    except:
                        sys.stderr.write('Custom operation now needs a || separator. Found: %s\n' % (text,))
                        raise

                    thread_id, frame_id, scopeattrs = location.split('\t', 2)

                    if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    # : style: EXECFILE or EXEC
                    # : encoded_code_or_file: file to execute or code
                    # : fname: name of function to be executed in the resulting namespace
                    style, encoded_code_or_file, fnname = custom.split('\t', 3)
                    int_cmd = InternalRunCustomOperation(seq, thread_id, frame_id, scope, attrs,
                                                         style, encoded_code_or_file, fnname)
                    py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_IGNORE_THROWN_EXCEPTION_AT:
                if text:
                    replace = 'REPLACE:'  # Not all 3.x versions support u'REPLACE:', so, doing workaround.
                    if not IS_PY3K:
                        replace = unicode(replace)

                    if text.startswith(replace):
                        text = text[8:]
                        py_db.filename_to_lines_where_exceptions_are_ignored.clear()

                    if text:
                        for line in text.split('||'):  # Can be bulk-created (one in each line)
                            filename, line_number = line.split('|')
                            if not IS_PY3K:
                                filename = filename.encode(file_system_encoding)

                            filename = pydevd_file_utils.norm_file_to_server(filename)

                            if os.path.exists(filename):
                                lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored.get(filename)
                                if lines_ignored is None:
                                    lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored[filename] = {}
                                lines_ignored[int(line_number)] = 1
                            else:
                                sys.stderr.write('pydev debugger: warning: trying to ignore exception thrown'\
                                    ' on file that does not exist: %s (will have no effect)\n' % (filename,))

            elif cmd_id == CMD_ENABLE_DONT_TRACE:
                if text:
                    true_str = 'true'  # Not all 3.x versions support u'str', so, doing workaround.
                    if not IS_PY3K:
                        true_str = unicode(true_str)

                    mode = text.strip() == true_str
                    pydevd_dont_trace.trace_filter(mode)

            elif cmd_id == CMD_REDIRECT_OUTPUT:
                if text:
                    py_db.enable_output_redirection('STDOUT' in text, 'STDERR' in text)

            elif cmd_id == CMD_GET_NEXT_STATEMENT_TARGETS:
                thread_id, frame_id = text.split('\t', 1)

                int_cmd = InternalGetNextStatementTargets(seq, thread_id, frame_id)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_PROJECT_ROOTS:
                pydevd_utils.set_project_roots(text.split(u'\t'))

            elif cmd_id == CMD_THREAD_DUMP_TO_STDERR:
                pydevd_utils.dump_threads()

            elif cmd_id == CMD_STOP_ON_START:
                py_db.stop_on_start = text.strip() in ('True', 'true', '1')
                
            elif cmd_id == CMD_PYDEVD_JSON_CONFIG:
                # Expected to receive a json string as:
                # {
                #     'skip_suspend_on_breakpoint_exception': [<exception names where we should suspend>],
                #     'skip_print_breakpoint_exception': [<exception names where we should print>],
                #     'multi_threads_single_notification': bool,
                # }
                msg = json.loads(text.strip())
                if 'skip_suspend_on_breakpoint_exception' in msg:
                    py_db.skip_suspend_on_breakpoint_exception = tuple(
                        get_exception_class(x) for x in msg['skip_suspend_on_breakpoint_exception'])
                
                if 'skip_print_breakpoint_exception' in msg:
                    py_db.skip_print_breakpoint_exception = tuple(
                        get_exception_class(x) for x in msg['skip_print_breakpoint_exception'])
                    
                if 'multi_threads_single_notification' in msg:
                    py_db.multi_threads_single_notification = msg['multi_threads_single_notification']

            elif cmd_id == CMD_GET_EXCEPTION_DETAILS:
                thread_id = text
                t = pydevd_find_thread_by_id(thread_id)
                frame = None
                if t and not getattr(t, 'pydev_do_not_trace', None):
                    additional_info = set_additional_thread_info(t)
                    frame = additional_info.get_topmost_frame(t)
                try:
                    cmd = py_db.cmd_factory.make_get_exception_details_message(seq, thread_id, frame)
                finally:
                    frame = None
                    t = None

            else:
                #I have no idea what this is all about
                cmd = py_db.cmd_factory.make_error_message(seq, "unexpected command " + str(cmd_id))

            if cmd is not None:
                py_db.writer.add_command(cmd)
                del cmd

        except Exception:
            traceback.print_exc()
            try:
                from StringIO import StringIO
            except ImportError:
                from io import StringIO
            stream = StringIO()
            traceback.print_exc(file=stream)
            cmd = py_db.cmd_factory.make_error_message(
                seq,
                "Unexpected exception in process_net_command.\nInitial params: %s. Exception: %s" % (
                    ((cmd_id, seq, text), stream.getvalue())
                )
            )

            py_db.writer.add_command(cmd)
    finally:
        py_db._main_lock.release()
Exemple #55
0
def process_net_command(py_db, cmd_id, seq, text):
    '''Processes a command received from the Java side

    @param cmd_id: the id of the command
    @param seq: the sequence of the command
    @param text: the text received in the command

    @note: this method is run as a big switch... after doing some tests, it's not clear whether changing it for
    a dict id --> function call will have better performance result. A simple test with xrange(10000000) showed
    that the gains from having a fast access to what should be executed are lost because of the function call in
    a way that if we had 10 elements in the switch the if..elif are better -- but growing the number of choices
    makes the solution with the dispatch look better -- so, if this gets more than 20-25 choices at some time,
    it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before
    probably will give better performance).
    '''
    # print(ID_TO_MEANING[str(cmd_id)], repr(text))

    py_db._main_lock.acquire()
    try:
        try:
            cmd = None
            if cmd_id == CMD_RUN:
                py_db.ready_to_run = True

            elif cmd_id == CMD_VERSION:
                # response is version number
                # ide_os should be 'WINDOWS' or 'UNIX'.
                ide_os = 'WINDOWS'

                # Breakpoints can be grouped by 'LINE' or by 'ID'.
                breakpoints_by = 'LINE'

                splitted = text.split('\t')
                if len(splitted) == 1:
                    _local_version = splitted

                elif len(splitted) == 2:
                    _local_version, ide_os = splitted

                elif len(splitted) == 3:
                    _local_version, ide_os, breakpoints_by = splitted

                if breakpoints_by == 'ID':
                    py_db._set_breakpoints_with_id = True
                else:
                    py_db._set_breakpoints_with_id = False

                pydevd_file_utils.set_ide_os(ide_os)

                cmd = py_db.cmd_factory.make_version_message(seq)

            elif cmd_id == CMD_LIST_THREADS:
                # response is a list of threads
                cmd = py_db.cmd_factory.make_list_threads_message(seq)

            elif cmd_id == CMD_THREAD_KILL:
                int_cmd = InternalTerminateThread(text)
                py_db.post_internal_command(int_cmd, text)

            elif cmd_id == CMD_THREAD_SUSPEND:
                # Yes, thread suspend is still done at this point, not through an internal command!
                t = pydevd_find_thread_by_id(text)
                if t and not hasattr(t, 'pydev_do_not_trace'):
                    additional_info = None
                    try:
                        additional_info = t.additional_info
                    except AttributeError:
                        pass  # that's ok, no info currently set

                    if additional_info is not None:
                        for frame in additional_info.iter_frames(t):
                            py_db.set_trace_for_frame_and_parents(frame, overwrite_prev_trace=True)
                            del frame

                    py_db.set_suspend(t, CMD_THREAD_SUSPEND)
                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't suspend tasklet: %s\n" % (text,))

            elif cmd_id == CMD_THREAD_RUN:
                t = pydevd_find_thread_by_id(text)
                if t:
                    t.additional_info.pydev_step_cmd = -1
                    t.additional_info.pydev_step_stop = None
                    t.additional_info.pydev_state = STATE_RUN

                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't make tasklet run: %s\n" % (text,))


            elif cmd_id == CMD_STEP_INTO or cmd_id == CMD_STEP_OVER or cmd_id == CMD_STEP_RETURN or \
                    cmd_id == CMD_STEP_INTO_MY_CODE:
                # we received some command to make a single step
                t = pydevd_find_thread_by_id(text)
                if t:
                    thread_id = get_thread_id(t)
                    int_cmd = InternalStepThread(thread_id, cmd_id)
                    py_db.post_internal_command(int_cmd, thread_id)

                elif text.startswith('__frame__:'):
                    sys.stderr.write("Can't make tasklet step command: %s\n" % (text,))


            elif cmd_id == CMD_RUN_TO_LINE or cmd_id == CMD_SET_NEXT_STATEMENT or cmd_id == CMD_SMART_STEP_INTO:
                # we received some command to make a single step
                thread_id, line, func_name = text.split('\t', 2)
                t = pydevd_find_thread_by_id(thread_id)
                if t:
                    int_cmd = InternalSetNextStatementThread(thread_id, cmd_id, line, func_name)
                    py_db.post_internal_command(int_cmd, thread_id)
                elif thread_id.startswith('__frame__:'):
                    sys.stderr.write("Can't set next statement in tasklet: %s\n" % (thread_id,))


            elif cmd_id == CMD_RELOAD_CODE:
                # we received some command to make a reload of a module
                module_name = text.strip()

                thread_id = '*'  # Any thread

                # Note: not going for the main thread because in this case it'd only do the load
                # when we stopped on a breakpoint.
                # for tid, t in py_db._running_thread_ids.items(): #Iterate in copy
                #    thread_name = t.getName()
                #
                #    print thread_name, get_thread_id(t)
                #    #Note: if possible, try to reload on the main thread
                #    if thread_name == 'MainThread':
                #        thread_id = tid

                int_cmd = ReloadCodeCommand(module_name, thread_id)
                py_db.post_internal_command(int_cmd, thread_id)


            elif cmd_id == CMD_CHANGE_VARIABLE:
                # the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change
                try:
                    thread_id, frame_id, scope, attr_and_value = text.split('\t', 3)

                    tab_index = attr_and_value.rindex('\t')
                    attr = attr_and_value[0:tab_index].replace('\t', '.')
                    value = attr_and_value[tab_index + 1:]
                    int_cmd = InternalChangeVariable(seq, thread_id, frame_id, scope, attr, value)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_VARIABLE:
                # we received some command to get a variable
                # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes*
                try:
                    thread_id, frame_id, scopeattrs = text.split('\t', 2)

                    if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    int_cmd = InternalGetVariable(seq, thread_id, frame_id, scope, attrs)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_ARRAY:
                # we received some command to get an array variable
                # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tname\ttemp\troffs\tcoffs\trows\tcols\tformat
                try:
                    roffset, coffset, rows, cols, format, thread_id, frame_id, scopeattrs  = text.split('\t', 7)

                    if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    int_cmd = InternalGetArray(seq, roffset, coffset, rows, cols, format, thread_id, frame_id, scope, attrs)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()

            elif cmd_id == CMD_SHOW_RETURN_VALUES:
                try:
                    show_return_values = text.split('\t')[1]
                    if int(show_return_values) == 1:
                        py_db.show_return_values = True
                    else:
                        if py_db.show_return_values:
                            # We should remove saved return values
                            py_db.remove_return_values_flag = True
                        py_db.show_return_values = False
                    pydev_log.debug("Show return values: %s\n" % py_db.show_return_values)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_COMPLETIONS:
                # we received some command to get a variable
                # the text is: thread_id\tframe_id\tactivation token
                try:
                    thread_id, frame_id, scope, act_tok = text.split('\t', 3)

                    int_cmd = InternalGetCompletions(seq, thread_id, frame_id, act_tok)
                    py_db.post_internal_command(int_cmd, thread_id)

                except:
                    traceback.print_exc()
            elif cmd_id == CMD_GET_DESCRIPTION:
                try:

                    thread_id, frame_id, expression = text.split('\t', 2)
                    int_cmd = InternalGetDescription(seq, thread_id, frame_id, expression)
                    py_db.post_internal_command(int_cmd, thread_id)
                except:
                    traceback.print_exc()

            elif cmd_id == CMD_GET_FRAME:
                thread_id, frame_id, scope = text.split('\t', 2)

                int_cmd = InternalGetFrame(seq, thread_id, frame_id)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_BREAK:
                # func name: 'None': match anything. Empty: match global, specified: only method context.
                # command to add some breakpoint.
                # text is file\tline. Add to breakpoints dictionary
                suspend_policy = "NONE"
                if py_db._set_breakpoints_with_id:
                    breakpoint_id, type, file, line, func_name, condition, expression = text.split('\t', 6)

                    breakpoint_id = int(breakpoint_id)
                    line = int(line)

                    # We must restore new lines and tabs as done in
                    # AbstractDebugTarget.breakpointAdded
                    condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').\
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                    expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n').\
                        replace("@_@TAB_CHAR@_@", '\t').strip()
                else:
                    #Note: this else should be removed after PyCharm migrates to setting
                    #breakpoints by id (and ideally also provides func_name).
                    type, file, line, func_name, suspend_policy, condition, expression = text.split('\t', 6)
                    # If we don't have an id given for each breakpoint, consider
                    # the id to be the line.
                    breakpoint_id = line = int(line)

                    condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                    expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n'). \
                        replace("@_@TAB_CHAR@_@", '\t').strip()

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    file = file.encode(file_system_encoding)

                file = pydevd_file_utils.norm_file_to_server(file)

                if not pydevd_file_utils.exists(file):
                    sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\
                        ' to file that does not exist: %s (will have no effect)\n' % (file,))
                    sys.stderr.flush()


                if len(condition) <= 0 or condition is None or condition == "None":
                    condition = None

                if len(expression) <= 0 or expression is None or expression == "None":
                    expression = None

                if type == 'python-line':
                    breakpoint = LineBreakpoint(line, condition, func_name, expression, suspend_policy)
                    breakpoints = py_db.breakpoints
                    file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
                    supported_type = True
                else:
                    result = None
                    plugin = py_db.get_plugin_lazy_init()
                    if plugin is not None:
                        result = plugin.add_breakpoint('add_line_breakpoint', py_db, type, file, line, condition, expression, func_name)
                    if result is not None:
                        supported_type = True
                        breakpoint, breakpoints = result
                        file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
                    else:
                        supported_type = False

                if not supported_type:
                    raise NameError(type)

                if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
                    pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name.encode('utf-8')))
                    sys.stderr.flush()

                if dict_contains(file_to_id_to_breakpoint, file):
                    id_to_pybreakpoint = file_to_id_to_breakpoint[file]
                else:
                    id_to_pybreakpoint = file_to_id_to_breakpoint[file] = {}

                id_to_pybreakpoint[breakpoint_id] = breakpoint
                py_db.consolidate_breakpoints(file, id_to_pybreakpoint, breakpoints)
                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)

            elif cmd_id == CMD_REMOVE_BREAK:
                #command to remove some breakpoint
                #text is type\file\tid. Remove from breakpoints dictionary
                breakpoint_type, file, breakpoint_id = text.split('\t', 2)

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    file = file.encode(file_system_encoding)

                file = pydevd_file_utils.norm_file_to_server(file)

                try:
                    breakpoint_id = int(breakpoint_id)
                except ValueError:
                    pydev_log.error('Error removing breakpoint. Expected breakpoint_id to be an int. Found: %s' % (breakpoint_id,))

                else:
                    file_to_id_to_breakpoint = None
                    if breakpoint_type == 'python-line':
                        breakpoints = py_db.breakpoints
                        file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
                    elif py_db.get_plugin_lazy_init() is not None:
                        result = py_db.plugin.get_breakpoints(py_db, breakpoint_type)
                        if result is not None:
                            file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
                            breakpoints = result

                    if file_to_id_to_breakpoint is None:
                        pydev_log.error('Error removing breakpoint. Cant handle breakpoint of type %s' % breakpoint_type)
                    else:
                        try:
                            id_to_pybreakpoint = file_to_id_to_breakpoint.get(file, {})
                            if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
                                existing = id_to_pybreakpoint[breakpoint_id]
                                sys.stderr.write('Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n' % (
                                    file, existing.line, existing.func_name.encode('utf-8'), breakpoint_id))

                            del id_to_pybreakpoint[breakpoint_id]
                            py_db.consolidate_breakpoints(file, id_to_pybreakpoint, breakpoints)
                            if py_db.plugin is not None:
                                py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

                        except KeyError:
                            pydev_log.error("Error removing breakpoint: Breakpoint id not found: %s id: %s. Available ids: %s\n" % (
                                file, breakpoint_id, dict_keys(id_to_pybreakpoint)))


            elif cmd_id == CMD_EVALUATE_EXPRESSION or cmd_id == CMD_EXEC_EXPRESSION:
                #command to evaluate the given expression
                #text is: thread\tstackframe\tLOCAL\texpression
                temp_name = ""
                try:
                    thread_id, frame_id, scope, expression, trim, temp_name = text.split('\t', 5)
                except ValueError:
                    thread_id, frame_id, scope, expression, trim = text.split('\t', 4)
                int_cmd = InternalEvaluateExpression(seq, thread_id, frame_id, expression,
                    cmd_id == CMD_EXEC_EXPRESSION, int(trim) == 1, temp_name)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_CONSOLE_EXEC:
                #command to exec expression in console, in case expression is only partially valid 'False' is returned
                #text is: thread\tstackframe\tLOCAL\texpression

                thread_id, frame_id, scope, expression = text.split('\t', 3)

                int_cmd = InternalConsoleExec(seq, thread_id, frame_id, expression)
                py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_SET_PY_EXCEPTION:
                # Command which receives set of exceptions on which user wants to break the debugger
                # text is: break_on_uncaught;break_on_caught;TypeError;ImportError;zipimport.ZipImportError;
                # This API is optional and works 'in bulk' -- it's possible
                # to get finer-grained control with CMD_ADD_EXCEPTION_BREAK/CMD_REMOVE_EXCEPTION_BREAK
                # which allows setting caught/uncaught per exception.
                #
                splitted = text.split(';')
                py_db.break_on_uncaught_exceptions = {}
                py_db.break_on_caught_exceptions = {}
                added = []
                if len(splitted) >= 4:
                    if splitted[0] == 'true':
                        break_on_uncaught = True
                    else:
                        break_on_uncaught = False

                    if splitted[1] == 'true':
                        break_on_caught = True
                    else:
                        break_on_caught = False

                    if splitted[2] == 'true':
                        py_db.break_on_exceptions_thrown_in_same_context = True
                    else:
                        py_db.break_on_exceptions_thrown_in_same_context = False

                    if splitted[3] == 'true':
                        py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = True
                    else:
                        py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = False

                    for exception_type in splitted[4:]:
                        exception_type = exception_type.strip()
                        if not exception_type:
                            continue

                        exception_breakpoint = py_db.add_break_on_exception(
                            exception_type,
                            notify_always=break_on_caught,
                            notify_on_terminate=break_on_uncaught,
                            notify_on_first_raise_only=False,
                        )
                        if exception_breakpoint is None:
                            continue
                        added.append(exception_breakpoint)

                    py_db.update_after_exceptions_added(added)

                else:
                    sys.stderr.write("Error when setting exception list. Received: %s\n" % (text,))

            elif cmd_id == CMD_GET_FILE_CONTENTS:

                if not IS_PY3K:  # In Python 3, the frame object will have unicode for the file, whereas on python 2 it has a byte-array encoded with the filesystem encoding.
                    text = text.encode(file_system_encoding)

                if os.path.exists(text):
                    f = open(text, 'r')
                    try:
                        source = f.read()
                    finally:
                        f.close()
                    cmd = py_db.cmd_factory.make_get_file_contents(seq, source)

            elif cmd_id == CMD_SET_PROPERTY_TRACE:
                # Command which receives whether to trace property getter/setter/deleter
                # text is feature_state(true/false);disable_getter/disable_setter/disable_deleter
                if text != "":
                    splitted = text.split(';')
                    if len(splitted) >= 3:
                        if py_db.disable_property_trace is False and splitted[0] == 'true':
                            # Replacing property by custom property only when the debugger starts
                            pydevd_traceproperty.replace_builtin_property()
                            py_db.disable_property_trace = True
                        # Enable/Disable tracing of the property getter
                        if splitted[1] == 'true':
                            py_db.disable_property_getter_trace = True
                        else:
                            py_db.disable_property_getter_trace = False
                        # Enable/Disable tracing of the property setter
                        if splitted[2] == 'true':
                            py_db.disable_property_setter_trace = True
                        else:
                            py_db.disable_property_setter_trace = False
                        # Enable/Disable tracing of the property deleter
                        if splitted[3] == 'true':
                            py_db.disable_property_deleter_trace = True
                        else:
                            py_db.disable_property_deleter_trace = False
                else:
                    # User hasn't configured any settings for property tracing
                    pass

            elif cmd_id == CMD_ADD_EXCEPTION_BREAK:
                if text.find('\t') != -1:
                    exception, notify_always, notify_on_terminate, ignore_libraries = text.split('\t', 3)
                else:
                    exception, notify_always, notify_on_terminate, ignore_libraries = text, 0, 0, 0

                if exception.find('-') != -1:
                    breakpoint_type, exception = exception.split('-')
                else:
                    breakpoint_type = 'python'

                if breakpoint_type == 'python':
                    if int(notify_always) == 1:
                        pydev_log.warn("Deprecated parameter: 'notify always' policy removed in PyCharm\n")
                    exception_breakpoint = py_db.add_break_on_exception(
                        exception,
                        notify_always=int(notify_always) > 0,
                        notify_on_terminate = int(notify_on_terminate) == 1,
                        notify_on_first_raise_only=int(notify_always) == 2,
                        ignore_libraries=int(ignore_libraries) > 0
                    )

                    if exception_breakpoint is not None:
                        py_db.update_after_exceptions_added([exception_breakpoint])
                else:
                    supported_type = False
                    plugin = py_db.get_plugin_lazy_init()
                    if plugin is not None:
                        supported_type = plugin.add_breakpoint('add_exception_breakpoint', py_db, breakpoint_type, exception)

                    if supported_type:
                        py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
                    else:
                        raise NameError(breakpoint_type)



            elif cmd_id == CMD_REMOVE_EXCEPTION_BREAK:
                exception = text
                if exception.find('-') != -1:
                    exception_type, exception = exception.split('-')
                else:
                    exception_type = 'python'

                if exception_type == 'python':
                    try:
                        cp = py_db.break_on_uncaught_exceptions.copy()
                        dict_pop(cp, exception, None)
                        py_db.break_on_uncaught_exceptions = cp

                        cp = py_db.break_on_caught_exceptions.copy()
                        dict_pop(cp, exception, None)
                        py_db.break_on_caught_exceptions = cp
                    except:
                        pydev_log.debug("Error while removing exception %s"%sys.exc_info()[0])
                    update_exception_hook(py_db)
                else:
                    supported_type = False

                    # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
                    # anything from it anyways).
                    plugin = py_db.plugin
                    if plugin is not None:
                        supported_type = plugin.remove_exception_breakpoint(py_db, exception_type, exception)

                    if supported_type:
                        py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks()
                    else:
                        raise NameError(exception_type)

            elif cmd_id == CMD_LOAD_SOURCE:
                path = text
                try:
                    f = open(path, 'r')
                    source = f.read()
                    py_db.cmd_factory.make_load_source_message(seq, source, py_db)
                except:
                    return py_db.cmd_factory.make_error_message(seq, pydevd_tracing.get_exception_traceback_str())

            elif cmd_id == CMD_ADD_DJANGO_EXCEPTION_BREAK:
                exception = text
                plugin = py_db.get_plugin_lazy_init()
                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()


            elif cmd_id == CMD_REMOVE_DJANGO_EXCEPTION_BREAK:
                exception = text

                # I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
                # anything from it anyways).
                plugin = py_db.plugin
                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()

            elif cmd_id == CMD_EVALUATE_CONSOLE_EXPRESSION:
                # Command which takes care for the debug console communication
                if text != "":
                    thread_id, frame_id, console_command = text.split('\t', 2)
                    console_command, line = console_command.split('\t')

                    if console_command == 'EVALUATE':
                        int_cmd = InternalEvaluateConsoleExpression(
                            seq, thread_id, frame_id, line, buffer_output=True)

                    elif console_command == 'EVALUATE_UNBUFFERED':
                        int_cmd = InternalEvaluateConsoleExpression(
                            seq, thread_id, frame_id, line, buffer_output=False)

                    elif console_command == 'GET_COMPLETIONS':
                        int_cmd = InternalConsoleGetCompletions(seq, thread_id, frame_id, line)

                    else:
                        raise ValueError('Unrecognized command: %s' % (console_command,))

                    py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_RUN_CUSTOM_OPERATION:
                # Command which runs a custom operation
                if text != "":
                    try:
                        location, custom = text.split('||', 1)
                    except:
                        sys.stderr.write('Custom operation now needs a || separator. Found: %s\n' % (text,))
                        raise

                    thread_id, frame_id, scopeattrs = location.split('\t', 2)

                    if scopeattrs.find('\t') != -1:  # there are attributes beyond scope
                        scope, attrs = scopeattrs.split('\t', 1)
                    else:
                        scope, attrs = (scopeattrs, None)

                    # : style: EXECFILE or EXEC
                    # : encoded_code_or_file: file to execute or code
                    # : fname: name of function to be executed in the resulting namespace
                    style, encoded_code_or_file, fnname = custom.split('\t', 3)
                    int_cmd = InternalRunCustomOperation(seq, thread_id, frame_id, scope, attrs,
                                                         style, encoded_code_or_file, fnname)
                    py_db.post_internal_command(int_cmd, thread_id)

            elif cmd_id == CMD_IGNORE_THROWN_EXCEPTION_AT:
                if text:
                    replace = 'REPLACE:'  # Not all 3.x versions support u'REPLACE:', so, doing workaround.
                    if not IS_PY3K:
                        replace = unicode(replace)

                    if text.startswith(replace):
                        text = text[8:]
                        py_db.filename_to_lines_where_exceptions_are_ignored.clear()

                    if text:
                        for line in text.split('||'):  # Can be bulk-created (one in each line)
                            filename, line_number = line.split('|')
                            if not IS_PY3K:
                                filename = filename.encode(file_system_encoding)

                            filename = pydevd_file_utils.norm_file_to_server(filename)

                            if os.path.exists(filename):
                                lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored.get(filename)
                                if lines_ignored is None:
                                    lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored[filename] = {}
                                lines_ignored[int(line_number)] = 1
                            else:
                                sys.stderr.write('pydev debugger: warning: trying to ignore exception thrown'\
                                    ' on file that does not exist: %s (will have no effect)\n' % (filename,))

            elif cmd_id == CMD_ENABLE_DONT_TRACE:
                if text:
                    true_str = 'true'  # Not all 3.x versions support u'str', so, doing workaround.
                    if not IS_PY3K:
                        true_str = unicode(true_str)

                    mode = text.strip() == true_str
                    pydevd_dont_trace.trace_filter(mode)

            else:
                #I have no idea what this is all about
                cmd = py_db.cmd_factory.make_error_message(seq, "unexpected command " + str(cmd_id))

            if cmd is not None:
                py_db.writer.add_command(cmd)
                del cmd

        except Exception:
            traceback.print_exc()
            from _pydev_bundle.pydev_imports import StringIO
            stream = StringIO()
            traceback.print_exc(file=stream)
            cmd = py_db.cmd_factory.make_error_message(
                seq,
                "Unexpected exception in process_net_command.\nInitial params: %s. Exception: %s" % (
                    ((cmd_id, seq, text), stream.getvalue())
                )
            )

            py_db.writer.add_command(cmd)
    finally:
        py_db._main_lock.release()
Exemple #56
0
def log_debug(msg):
    pydev_log.debug(msg)
    def _map_file_to_client(filename, cache=norm_filename_to_client_container):
        # The result of this method will be passed to eclipse
        # So, this would be 'NormFileFromPythonToEclipse'
        try:
            return cache[filename]
        except KeyError:
            abs_path = absolute_path(filename)
            translated_proper_case = get_path_with_real_case(abs_path)
            translated_normalized = normcase(abs_path)

            path_mapping_applied = False

            if translated_normalized.lower() != translated_proper_case.lower():
                if DEBUG_CLIENT_SERVER_TRANSLATION:
                    pydev_log.critical(
                        'pydev debugger: translated_normalized changed path (from: %s to %s)',
                        translated_proper_case, translated_normalized)

            for i, (eclipse_prefix,
                    python_prefix) in enumerate(paths_from_eclipse_to_python):
                if translated_normalized.startswith(python_prefix):
                    if DEBUG_CLIENT_SERVER_TRANSLATION:
                        pydev_log.critical(
                            'pydev debugger: replacing to client: %s',
                            translated_normalized)

                    # Note: use the non-normalized version.
                    eclipse_prefix = initial_paths[i][0]
                    translated = eclipse_prefix + translated_proper_case[
                        len(python_prefix):]
                    if DEBUG_CLIENT_SERVER_TRANSLATION:
                        pydev_log.critical(
                            'pydev debugger: sent to client: %s', translated)
                    path_mapping_applied = True
                    break
            else:
                if DEBUG_CLIENT_SERVER_TRANSLATION:
                    pydev_log.critical(
                        'pydev debugger: to client: unable to find matching prefix for: %s in %s',
                        translated_normalized,
                        [x[1] for x in paths_from_eclipse_to_python])
                translated = translated_proper_case

            if eclipse_sep != python_sep:
                translated = translated.replace(python_sep, eclipse_sep)

            translated = _path_to_expected_str(translated)

            # The resulting path is not in the python process, so, we cannot do a normalize the path here,
            # only at the beginning of this method.
            cache[filename] = (translated, path_mapping_applied)

            if translated not in _client_filename_in_utf8_to_source_reference:
                if path_mapping_applied:
                    source_reference = 0
                else:
                    source_reference = _next_source_reference()
                    pydev_log.debug(
                        'Created source reference: %s for untranslated path: %s',
                        source_reference, filename)

                _client_filename_in_utf8_to_source_reference[
                    translated] = source_reference
                _source_reference_to_server_filename[
                    source_reference] = filename

            return (translated, path_mapping_applied)
def log_debug(msg):
    from _pydev_bundle import pydev_log
    pydev_log.debug(msg)
 def do_kill_pydev_thread(self):
     if not self._kill_received:
         pydev_log.debug('%s received kill signal', self.name)
         self._kill_received = True