Beispiel #1
0
def setbreak(line=None, file=None, cond=None, temp=0, frame=None, throw=False):
    """set a breakpoint or a given line in file with conditional
    
    arguments:
        line - line number on which to break
        file - module or filename where the breakpoint should be set
        cond - string with conditional expression, which (if given) must
            evaluate to true to break
        temp - if true, create a temporary breakpoint
    
    example usage:
    
        setbreak(42, "/path/to/universe.py", "name == 'hitchhiker'")
        setbreak(35, "package.module")

    see: http://groups.google.com/group/comp.lang.python/browse_thread/thread/103326200285cb07#
    """
    if frame is None:
        frame = sys._getframe().f_back
    if file is None:
        file = frame.f_code.co_filename
    elif not file.startswith("file:") and os.path.sep not in file:
        try:
            mod = __import__(file, globals(), locals(), ["__file__"])
        except ImportError as err:
            if throw:
                raise
            sys.__stdout__.write("cannot set breakpoint: %s:%s : %s" %
                (file, line, err))
            return
        file = mod.__file__
        sys.__stdout__.write("breaking in: %s" % file)
    if file.endswith(".pyc"):
        file = file[:-1]
    pdb = Pdb(stdout=sys.__stdout__) # use sys.__stdout__ to work with nose tests
    pdb.reset()
    pdb.curframe = frame
    while frame:
        frame.f_trace = pdb.trace_dispatch
        pdb.botframe = frame
        frame = frame.f_back
    templine = line
    while templine < line + 10:
        error = pdb.set_break(file, templine, cond=cond, temporary=temp)
        if error:
            templine += 1
        else:
            break
    if error:
        error = pdb.set_break(file, line, cond=cond, temporary=temp)
        if throw:
            raise Error(error)
        sys.__stdout__.write("\n%s\n" % error)
        return
    sys.__stdout__.write("\n")
    pdb.do_break("") # print breakpoints
    pdb.set_continue()
    sys.settrace(pdb.trace_dispatch)
Beispiel #2
0
    def handle_debug_request(self, environ, start_response):
        if environ['REQUEST_METHOD'] != 'POST':
            LOG.debug("Request method invalid.")
            start_response('405 Method Not Allowed', [])
            return []

        request_headers = get_headers(environ)
        debug_token = request_headers[self.debug_header]
        LOG.debug("Unpacking context from debug header '%s: %s'",
                  self.debug_header, debug_token)
        obj = self.unpack_header(request_headers[self.debug_header])

        if obj is None:
            LOG.debug("Debug header invalid.")
            start_response("400 Bad Request", [])
            return []

        LOG.debug("Successfully unpacked: %s", obj)

        infile = environ['wsgi.input']
        input_encoding = get_content_charset(request_headers)
        outfile = StringIO()
        debugger = Pdb(stdin=BytesIO(), stdout=outfile)

        LOG.debug("Setting up the debugger.")
        if isinstance(obj, Traceback):
            # Start up the request Pdb debugger
            debugger.setup(None, obj)
            debugger.botframe = obj.tb_frame

        elif isinstance(obj, tuple):
            # It was a state-save of the pdb obj
            lineno, stack, curindex, curframe, cfl, btfm = obj
            debugger.lineno = lineno
            debugger.stack = stack
            debugger.curindex = curindex
            debugger.curframe = curframe
            debugger.curframe_locals = cfl
            debugger.botframe = btfm

        else:
            LOG.debug("Unknown context: %r", obj)
            start_response("500 Internal Server Error", [])
            return []

        # Read the text from the input stream
        n = min(
            int(request_headers.get(
                'content-length', self.max_content_length)),
            self.max_content_length
        )
        LOG.debug("Reading at most %d bytes from client.", n)
        text_bytes = infile.read(n)
        LOG.debug("Converting bytes to text using charset %r",
                  input_encoding)
        text = text_bytes.decode(input_encoding)

        LOG.debug("Sending command to debugger: %r", text)
        stop = debugger.onecmd(text)

        response = outfile.getvalue()
        LOG.debug("Debugger response: %r", response)

        headers = [("Content-Type", "text/plain; charset=utf-8")]

        if stop:
            LOG.debug("Done debugging. Not sending a header.")

        else:
            # Save the state of the debugger
            state = (
                debugger.lineno,
                debugger.stack,
                debugger.curindex,
                debugger.curframe,
                debugger.curframe_locals,
                debugger.botframe
            )
            LOG.debug("Debugger state: %r", state)
            LOG.debug("Packing debugger state into debug header: %s",
                      self.debug_header)
            debug_header = self.pack_header(state)
            LOG.debug("Debug header (%d bytes): %s",
                      len(debug_header), debug_header)
            headers.append((self.debug_header, debug_header))

        start_response("200 OK", headers)
        return [response.encode('utf-8')]