Beispiel #1
0
def default_should_trace_hook(frame, filename):
    '''
    Return True if this frame should be traced, False if tracing should be blocked.
    '''
    # First, check whether this code object has a cached value
    ignored_lines = _filename_to_ignored_lines.get(filename)
    if ignored_lines is None:
        # Now, look up that line of code and check for a @DontTrace
        # preceding or on the same line as the method.
        # E.g.:
        # #@DontTrace
        # def test():
        #     pass
        #  ... or ...
        # def test(): #@DontTrace
        #     pass
        ignored_lines = {}
        lines = linecache.getlines(filename)
        i_line = 0  # Could use enumerate, but not there on all versions...
        for line in lines:
            j = line.find('#')
            if j >= 0:
                comment = line[j:]
                if DONT_TRACE_TAG in comment:
                    ignored_lines[i_line] = 1

                    #Note: when it's found in the comment, mark it up and down for the decorator lines found.
                    k = i_line - 1
                    while k >= 0:
                        if RE_DECORATOR.match(lines[k]):
                            ignored_lines[k] = 1
                            k -= 1
                        else:
                            break

                    k = i_line + 1
                    while k <= len(lines):
                        if RE_DECORATOR.match(lines[k]):
                            ignored_lines[k] = 1
                            k += 1
                        else:
                            break

            i_line += 1

        _filename_to_ignored_lines[filename] = ignored_lines

    func_line = frame.f_code.co_firstlineno - 1  # co_firstlineno is 1-based, so -1 is needed
    return not (DictContains(ignored_lines, func_line - 1)
                or  #-1 to get line before method 
                DictContains(ignored_lines, func_line))  #method line
Beispiel #2
0
def _get_template_file_name(frame):
    try:
        if IS_DJANGO19:
            # The Node source was removed since Django 1.9
            if DictContains(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(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:
            filename, base = GetFileNameAndBaseFromFile(fname)
            return filename
    except:
        pydev_log.debug(traceback.format_exc())
        return None
Beispiel #3
0
def stop(plugin, pydb, frame, event, args, stop_info, arg, step_cmd):
    pydb, filename, info, thread = args
    if DictContains(stop_info, 'jinja2_stop') and stop_info['jinja2_stop']:
        frame = _suspend_jinja2(pydb, thread, frame, step_cmd)
        if frame:
            pydb.doWaitSuspend(thread, frame, event, arg)
            return True
    return False
Beispiel #4
0
def stop(plugin, mainDebugger, frame, event, args, stop_info, arg, step_cmd):
    mainDebugger, filename, info, thread = args
    if DictContains(stop_info, 'django_stop') and stop_info['django_stop']:
        frame = suspend_django(mainDebugger, thread, frame, step_cmd)
        if frame:
            mainDebugger.doWaitSuspend(thread, frame, event, arg)
            return True
    return False
Beispiel #5
0
def _is_jinja2_render_call(frame):
    try:
        name = frame.f_code.co_name
        if DictContains(frame.f_globals, "__jinja_template__") and name in (
                "root", "loop", "macro") or name.startswith("block_"):
            return True
        return False
    except:
        traceback.print_exc()
        return False
Beispiel #6
0
 def get_task_id(self, frame):
     while frame is not None:
         if DictContains(frame.f_locals, "self"):
             self_obj = frame.f_locals["self"]
             if isinstance(self_obj,  asyncio.Task):
                 method_name = frame.f_code.co_name
                 if method_name == "_step":
                     return id(self_obj)
         frame = frame.f_back
     return None
Beispiel #7
0
def is_django_context_get_call(frame):
    try:
        if not DictContains(frame.f_locals, 'self'):
            return False

        cls = frame.f_locals['self'].__class__

        return inherits(cls, 'BaseContext')
    except:
        traceback.print_exc()
        return False
Beispiel #8
0
def _find_render_function_frame(frame):
    #in order to hide internal rendering functions
    old_frame = frame
    try:
        while not (DictContains(frame.f_locals, 'self') and frame.f_locals['self'].__class__.__name__ == 'Template' and \
                               frame.f_code.co_name == 'render'):
            frame = frame.f_back
            if frame is None:
                return old_frame
        return frame
    except:
        return old_frame
    def do_import(self, name, *args, **kwargs):
        activate_func = None
        if DictContains(self._modules_to_patch, name):
            activate_func = self._modules_to_patch.pop(name)

        module = self._system_import(name, *args, **kwargs)
        try:
            if activate_func:
                activate_func()  #call activate function
        except:
            sys.stderr.write("Matplotlib support failed")
        return module
Beispiel #10
0
def is_django_resolve_call(frame):
    try:
        name = frame.f_code.co_name
        if name != '_resolve_lookup':
            return False

        if not DictContains(frame.f_locals, 'self'):
            return False

        cls = frame.f_locals['self'].__class__

        clsname = cls.__name__
        return clsname == 'Variable'
    except:
        traceback.print_exc()
        return False
    def plugin_import(self,
                      name,
                      globals=None,
                      locals=None,
                      fromlist=None,
                      level=-2):
        import_name = name
        try:
            if self.enabled:
                ref_globals = globals
                if ref_globals is None:
                    ref_globals = sys._getframe(1).f_globals
                space = _discover_space(name, ref_globals)
                if space is not None:
                    actual_name = space._rewrite_module_path(name)
                    if actual_name is not None:
                        import_name = actual_name
        except:
            sys.stderr.write("Failed to get import name for name %s\n" % name)

        if level == -2:
            # fake impossible value; default value depends on version
            if IS_PY24:
                # the level parameter was added in version 2.5
                return self._system_import(import_name, globals, locals,
                                           fromlist)
            elif IS_PY3K:
                # default value for level parameter in python 3
                level = 0
            else:
                # default value for level parameter in other versions
                level = -1
        if IS_JYTHON:
            import_name = name

        activate_func = None
        if name == import_name and DictContains(self._modules_to_patch, name):
            activate_func = DictPop(self._modules_to_patch, name)

        module = self._system_import(import_name, globals, locals, fromlist,
                                     level)
        try:
            if activate_func:
                activate_func()  #call activate function
        except:
            sys.stderr.write("Patching modules in pluginbase failed\n")
        return module
Beispiel #12
0
def cmd_step_over(plugin, pydb, frame, event, args, stop_info, stop):
    pydb, filename, info, thread = args
    plugin_stop = False
    stop_info['jinja2_stop'] = False
    if not hasattr(info, 'pydev_call_from_jinja2'):
        info.pydev_call_from_jinja2 = None
    if not hasattr(info, 'pydev_call_inside_jinja2'):
        info.pydev_call_inside_jinja2 = None
    if _is_jinja2_suspended(thread):
        stop = False

        if info.pydev_call_inside_jinja2 is None:
            if _is_jinja2_render_call(frame):
                if event == 'call':
                    info.pydev_call_inside_jinja2 = frame.f_back
                if event in ('line', 'return'):
                    info.pydev_call_inside_jinja2 = frame
        else:
            if event == 'line':
                if _is_jinja2_render_call(
                        frame) and info.pydev_call_inside_jinja2 is frame:
                    stop_info['jinja2_stop'] = True
                    plugin_stop = stop_info['jinja2_stop']
            if event == 'return':
                if frame is info.pydev_call_inside_jinja2 and not DictContains(
                        frame.f_back.f_locals, 'event'):
                    info.pydev_call_inside_jinja2 = _find_jinja2_render_frame(
                        frame.f_back)
        return stop, plugin_stop
    else:
        if event == 'return' and _is_jinja2_context_call(frame.f_back):
            #we return from python code to Jinja2 rendering frame
            info.pydev_call_from_jinja2 = None
            info.pydev_call_inside_jinja2 = _find_jinja2_render_frame(frame)
            thread.additionalInfo.suspend_type = JINJA2_SUSPEND
            stop = False
            return stop, plugin_stop
    #print "info.pydev_call_from_jinja2", info.pydev_call_from_jinja2, "stop", stop, "jinja_stop", jinja2_stop, \
    #    "thread.additionalInfo.suspend_type", thread.additionalInfo.suspend_type
    #print "event", event, "info.pydev_call_inside_jinja2", info.pydev_call_inside_jinja2
    #print "frame", frame, "frame.f_back", frame.f_back, "step_stop", info.pydev_step_stop
    #print "is_context_call", _is_jinja2_context_call(frame)
    #print "render", _is_jinja2_render_call(frame)
    #print "-------------"
    return stop, plugin_stop
Beispiel #13
0
def _get_jinja2_template_line(frame):
    debug_info = None
    if DictContains(frame.f_globals, '__jinja_template__'):
        _debug_info = frame.f_globals['__jinja_template__']._debug_info
        if _debug_info != '':
            #sometimes template contains only plain text
            debug_info = frame.f_globals['__jinja_template__'].debug_info

    if debug_info is None:
        return None

    lineno = frame.f_lineno

    for pair in debug_info:
        if pair[1] == lineno:
            return pair[0]

    return None
Beispiel #14
0
def is_django_render_call(frame):
    try:
        name = frame.f_code.co_name
        if name != 'render':
            return False

        if not DictContains(frame.f_locals, 'self'):
            return False

        cls = frame.f_locals['self'].__class__

        inherits_node = inherits(cls, 'Node')

        if not inherits_node:
            return False

        clsname = cls.__name__
        return clsname != 'TextNode' and clsname != 'NodeList'
    except:
        traceback.print_exc()
        return False
Beispiel #15
0
def get_breakpoint(plugin, pydb, pydb_frame, frame, event, args):
    pydb, filename, info, thread = args
    new_frame = None
    jinja2_breakpoint = None
    flag = False
    if event in ('line', 'call') and info.pydev_state != STATE_SUSPEND and hasattr(pydb, 'jinja2_breakpoints') and \
            pydb.jinja2_breakpoints and cached_call(pydb_frame, is_jinja2_render_call, frame):
        filename = get_jinja2_template_filename(frame)
        jinja2_breakpoints_for_file = pydb.jinja2_breakpoints.get(filename)
        new_frame = Jinja2TemplateFrame(frame)

        if jinja2_breakpoints_for_file:
            lineno = frame.f_lineno
            template_lineno = get_jinja2_template_line(frame)
            if template_lineno is not None and DictContains(
                    jinja2_breakpoints_for_file, template_lineno):
                jinja2_breakpoint = jinja2_breakpoints_for_file[
                    template_lineno]
                flag = True
                new_frame = Jinja2TemplateFrame(frame)

    return flag, jinja2_breakpoint, new_frame
Beispiel #16
0
def get_breakpoint(plugin, mainDebugger, pydb_frame, frame, event, args):
    mainDebugger, filename, info, thread = args
    flag = False
    django_breakpoint = None
    new_frame = None
    type = 'django'

    if event == 'call' and info.pydev_state != STATE_SUSPEND and \
            mainDebugger.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 = mainDebugger.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 DictContains(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
Beispiel #17
0
 def do_import(self,
               name,
               globals=None,
               locals=None,
               fromlist=None,
               level=-2):
     if level == -2:
         # fake impossible value; default value depends on version
         if IS_PY24:
             # the level parameter was added in version 2.5
             return self._system_import(name, globals, locals, fromlist)
         elif IS_PY3K:
             # default value for level parameter in python 3
             level = 0
         else:
             # default value for level parameter in other versions
             level = -1
     module = self._system_import(name, globals, locals, fromlist, level)
     if DictContains(self._modules_to_patch, name):
         self._modules_to_patch[name]()  #call activate function
         self._modules_to_patch.pop(name)
     return module
Beispiel #18
0
 def changeVariable(self, name, value):
     for d in self.back_context.dicts:
         if DictContains(d, name):
             d[name] = value
     self.f_locals[name] = value
def get_referrer_info(searched_obj):
    try:
        if searched_obj is None:
            ret = ['<xml>\n']

            ret.append('<for>\n')
            ret.append(
                pydevd_vars.varToXML(searched_obj,
                                     'Skipping getting referrers for None',
                                     ' id="%s"' % (id(searched_obj), )))
            ret.append('</for>\n')
            ret.append('</xml>')
            ret = ''.join(ret)
            return ret

        obj_id = id(searched_obj)

        try:
            import gc
            referrers = gc.get_referrers(searched_obj)
        except:
            import traceback
            traceback.print_exc()
            ret = ['<xml>\n']

            ret.append('<for>\n')
            ret.append(
                pydevd_vars.varToXML(
                    searched_obj,
                    'Exception raised while trying to get_referrers.',
                    ' id="%s"' % (id(searched_obj), )))
            ret.append('</for>\n')
            ret.append('</xml>')
            ret = ''.join(ret)
            return ret

            traceback.print_exc()

        curr_frame = sys._getframe()
        frame_type = type(curr_frame)

        #Ignore this frame and any caller frame of this frame

        ignore_frames = {
        }  #Should be a set, but it's not available on all python versions.
        while curr_frame is not None:
            if basename(curr_frame.f_code.co_filename).startswith('pydev'):
                ignore_frames[curr_frame] = 1
            curr_frame = curr_frame.f_back

        ret = ['<xml>\n']

        ret.append('<for>\n')
        ret.append(
            pydevd_vars.varToXML(searched_obj, 'Referrers of',
                                 ' id="%s"' % (obj_id, )))
        ret.append('</for>\n')

        all_objects = None

        for r in referrers:
            try:
                if DictContains(ignore_frames, r):
                    continue  #Skip the references we may add ourselves
            except:
                pass  #Ok: unhashable type checked...

            if r is referrers:
                continue

            r_type = type(r)
            r_id = str(id(r))

            representation = str(r_type)

            found_as = ''
            if r_type == frame_type:
                for key, val in r.f_locals.items():
                    if val is searched_obj:
                        found_as = key
                        break

            elif r_type == dict:
                # Try to check if it's a value in the dict (and under which key it was found)
                for key, val in r.items():
                    if val is searched_obj:
                        found_as = key
                        break

                #Ok, there's one annoying thing: many times we find it in a dict from an instance,
                #but with this we don't directly have the class, only the dict, so, to workaround that
                #we iterate over all reachable objects ad check if one of those has the given dict.
                if all_objects is None:
                    all_objects = gc.get_objects()

                for x in all_objects:
                    if getattr(x, '__dict__', None) is r:
                        r = x
                        r_type = type(x)
                        r_id = str(id(r))
                        representation = str(r_type)
                        break

            elif r_type in (tuple, list):

                #Don't use enumerate() because not all Python versions have it.
                i = 0
                for x in r:
                    if x is searched_obj:
                        found_as = '%s[%s]' % (r_type.__name__, i)
                        break
                    i += 1

            if found_as:
                found_as = ' found_as="%s"' % (
                    pydevd_vars.makeValidXmlValue(found_as), )

            ret.append(
                pydevd_vars.varToXML(r, representation,
                                     ' id="%s"%s' % (r_id, found_as)))
    finally:
        #If we have any exceptions, don't keep dangling references from this frame to any of our objects.
        all_objects = None
        referrers = None
        searched_obj = None
        r = None
        x = None
        key = None
        val = None
        curr_frame = None
        ignore_frames = None

    ret.append('</xml>')
    ret = ''.join(ret)
    return ret
Beispiel #20
0
    def log_event(self, frame):
        event_time = cur_time() - self.start_time

        # Debug loop iterations
        # if isinstance(self_obj, asyncio.base_events.BaseEventLoop):
        #     if method_name == "_run_once":
        #         print("Loop iteration")

        if not hasattr(frame, "f_back") or frame.f_back is None:
            return

        back = frame.f_back
        method_name = back.f_code.co_name

        if DictContains(frame.f_locals, "self"):
            self_obj = frame.f_locals["self"]
            if isinstance(self_obj, asyncio.Task):
                if method_name in ("__init__",):
                    task_id = id(self_obj)
                    task_name = self.task_mgr.get(str(task_id))
                    send_message("asyncio_event", event_time, task_name, task_name, "thread", "start", frame.f_code.co_filename,
                                 frame.f_lineno, frame)

            method_name = frame.f_code.co_name
            if isinstance(self_obj, asyncio.Lock):
                if method_name in ("acquire", "release"):
                    task_id = self.get_task_id(frame)
                    task_name = self.task_mgr.get(str(task_id))

                    if method_name == "acquire":
                        if not self_obj._waiters and not self_obj.locked():
                            send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                         method_name+"_begin", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))
                        if self_obj.locked():
                            method_name += "_begin"
                        else:
                            method_name += "_end"
                    elif method_name == "release":
                        method_name += "_end"

                    send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                 method_name, frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))

            if isinstance(self_obj, asyncio.Queue):
                if method_name in ("put", "get", "_put", "_get"):
                    task_id = self.get_task_id(frame)
                    task_name = self.task_mgr.get(str(task_id))

                    if method_name == "put":
                        send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                     "acquire_begin", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))
                    elif method_name == "_put":
                        send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                     "acquire_end", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))
                        send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                     "release", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))
                    elif method_name == "get":
                        back = frame.f_back
                        if back.f_code.co_name != "send":
                            send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                         "acquire_begin", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))
                        else:
                            send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                         "acquire_end", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))
                            send_message("asyncio_event", event_time, task_name, task_name, "lock",
                                         "release", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj)))
Beispiel #21
0
def error_once(message):
    if not DictContains(WARN_ONCE_MAP, message):
        WARN_ONCE_MAP[message] = True
        error(message)
Beispiel #22
0
    def log_event(self, frame):
        write_log = False
        self_obj = None
        if DictContains(frame.f_locals, "self"):
            self_obj = frame.f_locals["self"]
            if isinstance(self_obj, threading.Thread) or self_obj.__class__ == ObjectWrapper:
                write_log = True

        try:
            if write_log:
                t = threadingCurrentThread()
                back = frame.f_back
                if not back:
                    return
                name, back_base = pydevd_file_utils.GetFilenameAndBase(back)
                event_time = cur_time() - self.start_time
                method_name = frame.f_code.co_name

                if isinstance(self_obj, threading.Thread) and method_name in THREAD_METHODS:
                    if back_base not in DONT_TRACE_THREADING or \
                            (method_name in INNER_METHODS and back_base in INNER_FILES):
                        thread_id = GetThreadId(self_obj)
                        name = self_obj.getName()
                        real_method = frame.f_code.co_name
                        if real_method == "_stop":
                            # TODO: Python 2
                            if back_base in INNER_FILES and \
                                            back.f_code.co_name == "_wait_for_tstate_lock":
                                back = back.f_back.f_back
                            real_method = "stop"
                        elif real_method == "join":
                            # join called in the current thread, not in self object
                            thread_id = GetThreadId(t)
                            name = t.getName()

                        parent = None
                        if real_method in ("start", "stop"):
                            parent = GetThreadId(t)
                        send_message("threading_event", event_time, name, thread_id, "thread",
                        real_method, back.f_code.co_filename, back.f_lineno, back, parent=parent)
                        # print(event_time, self_obj.getName(), thread_id, "thread",
                        #       real_method, back.f_code.co_filename, back.f_lineno)

                if self_obj.__class__ == ObjectWrapper:
                    if back_base in DONT_TRACE_THREADING:
                        # do not trace methods called from threading
                        return
                    _, back_back_base = pydevd_file_utils.GetFilenameAndBase(back.f_back)
                    back = back.f_back
                    if back_back_base in DONT_TRACE_THREADING:
                        # back_back_base is the file, where the method was called froms
                        return
                    if method_name == "__init__":
                        send_message("threading_event", event_time, t.getName(), GetThreadId(t), "lock",
                                     method_name, back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(frame.f_locals["self"])))
                    if DictContains(frame.f_locals, "attr") and \
                            (frame.f_locals["attr"] in LOCK_METHODS or
                            frame.f_locals["attr"] in QUEUE_METHODS):
                        real_method = frame.f_locals["attr"]
                        if method_name == "call_begin":
                            real_method += "_begin"
                        elif method_name == "call_end":
                            real_method += "_end"
                        else:
                            return
                        if real_method == "release_end":
                            # do not log release end. Maybe use it later
                            return
                        send_message("threading_event", event_time, t.getName(), GetThreadId(t), "lock",
                        real_method, back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(self_obj)))

                        if real_method in ("put_end", "get_end"):
                            # fake release for queue, cause we don't call it directly
                            send_message("threading_event", event_time, t.getName(), GetThreadId(t), "lock",
                                         "release", back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(self_obj)))
                        # print(event_time, t.getName(), GetThreadId(t), "lock",
                        #       real_method, back.f_code.co_filename, back.f_lineno)

        except Exception:
            traceback.print_exc()
Beispiel #23
0
def _is_jinja2_context_call(frame):
    return DictContains(frame.f_locals, "_Context__obj")
Beispiel #24
0
def _is_jinja2_internal_function(frame):
    return DictContains(frame.f_locals, 'self') and frame.f_locals['self'].__class__.__name__ in \
        ('LoopContext', 'TemplateReference', 'Macro', 'BlockReference')
Beispiel #25
0
def _get_jinja2_template_filename(frame):
    if DictContains(frame.f_globals, '__jinja_template__'):
        fname = frame.f_globals['__jinja_template__'].filename
        filename, base = GetFileNameAndBaseFromFile(fname)
        return filename
    return None