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)
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')]