[Pydev-cvs] org.python.pydev.debug/pysrc pydevd_vars.py,NONE,1.1 pydevd.py,1.3,1.4 inspector.py,1.1,
Brought to you by:
fabioz
From: Aleksandar T. <at...@us...> - 2004-05-07 02:03:47
|
Update of /cvsroot/pydev/org.python.pydev.debug/pysrc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13484/pysrc Modified Files: pydevd.py Added Files: pydevd_vars.py Removed Files: inspector.py Log Message: Breakpoints, first cut Index: pydevd.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/pysrc/pydevd.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pydevd.py 28 Apr 2004 02:49:48 -0000 1.3 --- pydevd.py 7 May 2004 02:03:07 -0000 1.4 *************** *** 31,35 **** 108 STEP_OVER RDB thread_id 109 STEP_RETURN RDB thread_id ! 500 series diagnostics/ok 901 VERSION either Version string (1.0) Currently just used at startup --- 31,39 ---- 108 STEP_OVER RDB thread_id 109 STEP_RETURN RDB thread_id ! 110 GET_VARIABLE RDB var_locator GET_VARIABLE with XML of var content ! see code for definition ! 111 SET_BREAK RDB file/line of the breakpoint ! 112 REMOVE_BREAK RDB file/line of the return ! 500 series diagnostics/ok 901 VERSION either Version string (1.0) Currently just used at startup *************** *** 49,52 **** --- 53,57 ---- import time import inspect + import pydevd_vars VERSION_STRING = "1.0" *************** *** 61,64 **** --- 66,72 ---- CMD_STEP_OVER = 108 CMD_STEP_RETURN = 109 + CMD_GET_VARIABLE = 110 + CMD_SET_BREAK = 111 + CMD_REMOVE_BREAK = 112 CMD_VERSION = 501 CMD_RETURN = 502 *************** *** 102,106 **** log(2, "received command " + command) args = command.split('\t', 2) ! print "the args are", args[0], " 2 ", args[1], " 3 ", args[2] PyDB.instance.processNetCommand(int(args[0]), int(args[1]), args[2]) # print >>sys.stderr, "processed input" --- 110,114 ---- log(2, "received command " + command) args = command.split('\t', 2) ! # print "the args are", args[0], " 2 ", args[1], " 3 ", args[2] PyDB.instance.processNetCommand(int(args[0]), int(args[1]), args[2]) # print >>sys.stderr, "processed input" *************** *** 178,181 **** --- 186,190 ---- def makeErrorMessage(self, seq, text): cmd = NetCommand(CMD_ERROR, seq, text) + print >>sys.stderr, "Error: ", text return cmd; *************** *** 211,220 **** """ <xml> ! <thread id="id"/> ! <frame id="id" name="functionName " file="file" line="line"> """ try: cmdText = "<xml>" ! cmdText += '<thread id="' + str(thread_id) + '" ' + 'stop_reason="' + str(stop_reason) + '"/>' curFrame = frame while (curFrame): --- 220,232 ---- """ <xml> ! <thread id="id"> ! <frame id="id" name="functionName " file="file" line="line"> ! <var variable stuffff.... ! </frame> ! </thread> """ try: cmdText = "<xml>" ! cmdText += '<thread id="' + str(thread_id) + '" ' + 'stop_reason="' + str(stop_reason) + '">' curFrame = frame while (curFrame): *************** *** 224,235 **** myName = curFrame.f_code.co_name # print "name is ", myName ! myFile = inspect.getsourcefile(curFrame) or inspect.getfile(frame) # print "file is ", myFile myLine = str(curFrame.f_lineno) # print "line is ", myLine cmdText += '<frame id="' + myId +'" name="' + myName + '" ' ! cmdText += 'file="' + myFile + '" line="' + myLine + '"/>"' curFrame = curFrame.f_back ! cmdText += "</xml>" return NetCommand(CMD_THREAD_SUSPEND, 0, cmdText) except: --- 236,251 ---- myName = curFrame.f_code.co_name # print "name is ", myName ! myFile = curFrame.f_code.co_filename ! # myFile = inspect.getsourcefile(curFrame) or inspect.getfile(frame) # print "file is ", myFile myLine = str(curFrame.f_lineno) # print "line is ", myLine cmdText += '<frame id="' + myId +'" name="' + myName + '" ' ! cmdText += 'file="' + myFile + '" line="' + myLine + '">"' ! variables = pydevd_vars.frameVarsToXML(curFrame) ! cmdText += variables ! cmdText += "</frame>" curFrame = curFrame.f_back ! cmdText += "</thread></xml>" return NetCommand(CMD_THREAD_SUSPEND, 0, cmdText) except: *************** *** 242,245 **** --- 258,267 ---- return self.makeErrorMessage(0, sys.exc_info()[0]) + def makeGetVariableMessage(self, seq, payload): + try: + return NetCommand(CMD_GET_VARIABLE, seq, payload) + except Exception, e: + return self.makeErrorMessage(seq, str(e)) + INTERNAL_TERMINATE_THREAD = 1 INTERNAL_SUSPEND_THREAD = 2 *************** *** 269,272 **** --- 291,324 ---- sys.exit() + class InternalGetVariable: + """ gets the value of a variable """ + def __init__(self, seq, thread, frame_id, scope, attrs): + self.sequence = seq + self.thread = thread + self.frame_id = frame_id + self.scope = scope + self.attributes = attrs + + def doIt(self, dbg): + """ Converts request into python variable """ + try: + print >>sys.stderr, "getVar::doIt" + xml = "<xml>" + valDict = pydevd_vars.resolveCompoundVariable(self.thread, self.frame_id, self.scope, self.attributes) + print >>sys.stderr, "resolved variable" + keys = valDict.keys() + keys.sort() + for k in keys: + xml += pydevd_vars.varToXML(valDict[k], str(k)) + xml += "</xml>" + print >>sys.stderr, "done to xml" + cmd = dbg.cmdFactory.makeGetVariableMessage(self.sequence, xml) + print >>sys.stderr, "sending command" + dbg.writer.addCommand(cmd) + except Exception, e: + print >>sys.stderr, "ERROR RESOLVING", str(e) + cmd = dbg.cmdFactory.makeErrorMessage(self.sequence, "Error resolving variables" + str(e)) + dbg.writer.addCommand(cmd) + def findThreadById(thread_id): try: *************** *** 309,312 **** --- 361,365 ---- self.cmdFactory = NetCommandFactory() self.cmdQueue = {} # the hash of Queues. Key is thread id, value is thread + self.breakpoints = {} def initializeNetwork(self, sock): *************** *** 406,415 **** elif (id == CMD_THREAD_RUN): t = findThreadById(text) ! if t: t.pydev_state = PyDB.STATE_RUN elif (id == CMD_STEP_INTO or id == CMD_STEP_OVER or id == CMD_STEP_RETURN): t = findThreadById(text) if t: t.pydev_state = PyDB.STATE_RUN ! t.pydev_step_cmd = id else: cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(id)) --- 459,507 ---- elif (id == CMD_THREAD_RUN): t = findThreadById(text) ! if t: ! t.pydev_state = PyDB.STATE_RUN ! t.pydev_step_cmd = None elif (id == CMD_STEP_INTO or id == CMD_STEP_OVER or id == CMD_STEP_RETURN): t = findThreadById(text) if t: t.pydev_state = PyDB.STATE_RUN ! t.pydev_step_cmd = id ! elif (id == CMD_GET_VARIABLE): ! # text is: thread\tstackframe\tLOCAL|GLOBAL\tattributes* ! (thread_id, frame_id, scopeattrs) = text.split('\t', 2) ! if scopeattrs.find('\t') != -1: # there are attibutes beyond scope ! (scope, attrs) = scopeattrs.split('\t', 1) ! else: ! (scope, attrs) = (scopeattrs, None) ! t = findThreadById(thread_id) ! if t: ! int_cmd = InternalGetVariable(seq, t, frame_id, scope, attrs) ! self.postInternalCommand(int_cmd, thread_id) ! else: ! cmd = self.cmdFactory.makeErrorMessage(seq, "could not find thread for variable") ! elif (id == CMD_SET_BREAK): ! # text is file\tline. Add to breakpoints dictionary ! (file, line) = text.split('\t', 1) ! print "line is ", line ! print "file is ", file ! if self.breakpoints.has_key(file): ! breakDict = self.breakpoints[file] ! else: ! breakDict = {} ! breakDict[int(line)] = True ! self.breakpoints[file] = breakDict ! print >>sys.stderr, "Set breakpoint at ", file, line ! elif (id == CMD_REMOVE_BREAK): ! # text is file\tline. Remove from breakpoints dictionary ! (file, line) = text.split('\t', 1) ! line = int(line) ! if self.breakpoints.has_key(file): ! if self.breakpoints[file].has_key(line): ! del self.breakpoints[file][line] ! keys = self.breakpoints[file].keys() ! if len(keys) is 0: ! del self.breakpoints[file] ! else: ! print sys.stderr, "breakpoint not found", file, str(line) else: cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(id)) *************** *** 417,423 **** if cmd: self.writer.addCommand(cmd) ! except: ! print >>sys.stderr, "Unexpected exception in processNetCommand" ! print >>sys.stderr, sys.exc_info()[0] def processThreadNotAlive(self, thread): --- 509,517 ---- if cmd: self.writer.addCommand(cmd) ! except Exception, e: ! import traceback ! traceback.print_exc(e) ! cmd = self.cmdFactory.makeErrorMessage(seq, "Unexpected exception in processNetCommand:" + str(e)) ! self.writer.addCommand(cmd) def processThreadNotAlive(self, thread): *************** *** 456,460 **** thread.pydev_step_stop = None elif (thread.pydev_step_cmd == CMD_STEP_OVER): ! thread.pydev_step_stop = frame elif (thread.pydev_step_cmd == CMD_STEP_RETURN): thread.pydev_step_stop = frame.f_back --- 550,558 ---- thread.pydev_step_stop = None elif (thread.pydev_step_cmd == CMD_STEP_OVER): ! if (event is 'return'): # if we are returning from the function, stop in parent ! print "Stepping back one" ! thread.pydev_step_stop = frame.f_back ! else: ! thread.pydev_step_stop = frame elif (thread.pydev_step_cmd == CMD_STEP_RETURN): thread.pydev_step_stop = frame.f_back *************** *** 478,482 **** --- 576,587 ---- wasSuspended = False + + try: + """ breakpoints """ + file = frame.f_code.co_filename + line = int(frame.f_lineno) + if t.pydev_state != PyDB.STATE_SUSPEND and self.breakpoints.has_key(file) and self.breakpoints[file].has_key(line): + self.setSuspend(t, CMD_SET_BREAK) """ if thread has a suspend flag, we suspend with a busy wait """ if (t.pydev_state == PyDB.STATE_SUSPEND): *************** *** 485,488 **** --- 590,594 ---- return self.trace_dispatch except AttributeError: + print "Attribute ERROR" t.pydev_state = PyDB.STATE_RUN # assign it to avoid future exceptions except: *************** *** 491,500 **** raise ! if ( not wasSuspended and event == 'line'): """ step handling. We stop when we hit the right frame""" try: if (t.pydev_step_cmd == CMD_STEP_INTO): self.setSuspend(t, CMD_STEP_INTO) ! self.doWaitSuspend(t, frame, event, arg) elif (t.pydev_step_cmd == CMD_STEP_OVER or t.pydev_step_cmd == CMD_STEP_RETURN): if (t.pydev_step_stop == frame): --- 597,606 ---- raise ! if ( not wasSuspended and (event == 'line' or event== 'return')): """ step handling. We stop when we hit the right frame""" try: if (t.pydev_step_cmd == CMD_STEP_INTO): self.setSuspend(t, CMD_STEP_INTO) ! self.doWaitSuspend(t, frame, event, arg) elif (t.pydev_step_cmd == CMD_STEP_OVER or t.pydev_step_cmd == CMD_STEP_RETURN): if (t.pydev_step_stop == frame): --- inspector.py DELETED --- --- NEW FILE: pydevd_vars.py --- """ pydevd_vars deals with variables: resolution/conversion to XML. """ from types import * import urllib import threading import sys class VariableError(Exception): def __init__(self, message): Exception.__init__(self, message) class Resolver: """ prototype resolver class. Every container type should have a resolver that converts its members into a dictionary """ def resolve(self, var, attribute): if attribute is "implement": return "me" def getDictionary(self, var): return { "implement" : "me", "volunteers" : "needed" } class DictResolver(Resolver): def resolve(self, var, attribute): return var[attribute] def getDictionary(self, var): return var class ObjectResolver(Resolver): def resolve(self, var, attribute): if attribute is "__class__": return var.__class__ return getattr(var, attribute) def getDictionary(self, var): newDict = vars(var).copy() newDict['__class__'] = var.__class__ return newDict class TupleResolver(Resolver): def resolve(self, var, attribute): return var[int(attribute)] def getDictionary(self, var): newDict = {} i = 0; for x in var: newDict[i] = x i += 1 return newDict defaultResolver = Resolver() dictResolver = DictResolver() objectResolver = ObjectResolver() tupleResolver = TupleResolver() def getType(o): """ returns a triple (typeObject, typeString, resolver resolver != None means that variable is a container, and should be displayed as a hierarchy. Use the resolver to get its attributes. All container objects should have a resolver. """ if isinstance(o, NoneType): return (NoneType, "None", None) if isinstance(o, IntType): return (IntType, "int", None) if isinstance(o, LongType): return (LongType, "long", None) if isinstance(o, FloatType): return (FloatType, "float", None) if isinstance(o, BooleanType): return (BooleanType, "boolean", None) if isinstance(o, ComplexType): return (ComplexType, "ComplexType", None) if isinstance(o, StringType): return (StringType, "string", None) if isinstance(o, UnicodeType): return (UnicodeType, "UnicodeType", None) if isinstance(o, BufferType): return (BufferType, "BufferType", None) if isinstance(o, TupleType): return (TupleType, "tuple", tupleResolver) if isinstance(o, ListType): return (ListType, "list", tupleResolver) if isinstance(o, DictType): return (DictType, "dict", dictResolver) if isinstance(o, FunctionType): return (FunctionType, "FunctionType", defaultResolver) if isinstance(o, LambdaType): return (LambdaType, "LambdaType", defaultResolver) if isinstance(o, GeneratorType): return (GeneratorType, "GeneratorType", None) if isinstance(o, ClassType): return (ClassType, "ClassType", defaultResolver) if isinstance(o, UnboundMethodType): return (UnboundMethodType, "UnboundMethodType", defaultResolver) if isinstance(o, InstanceType): return (InstanceType, "InstanceType", defaultResolver) if isinstance(o, BuiltinFunctionType): return (BuiltinFunctionType, "built-in function", None) if isinstance(o, BuiltinMethodType): return (BuiltinMethodType, "built-in method", None) if isinstance(o, ModuleType): return (ModuleType, "ModuleType", defaultResolver) if isinstance(o, FileType): return (FileType, "FileType", defaultResolver) if isinstance(o, XRangeType): return (XRangeType, "XRangeType", defaultResolver) if isinstance(o, TracebackType): return (TracebackType, "TracebackType", defaultResolver) if isinstance(o, FrameType): return (FrameType, "FrameType", defaultResolver) if isinstance(o, SliceType): return (SliceType, "SliceType", defaultResolver) if isinstance(o, EllipsisType): return (EllipsisType, "Ellipsis", defaultResolver) if isinstance(o, DictProxyType): return (DictProxyType, "DictProxyType", defaultResolver) if isinstance(o, NotImplementedType): return (NotImplementedType, "Not implemented type", None) if isinstance(o, ObjectType): return (ObjectType, "ObjectType", objectResolver) def varToXML(v, name): """ single variable or dictionary to xml representation """ xml = "" (type, typeName, resolver) = getType(v) value = str(v) xml += '<var name="' + name + '" type="' + typeName + '"' if value: xml += ' value="' + urllib.quote(value, '/>_= \t') + '"' if resolver is not None: xml += ' isContainer="True"' xml += ' />\n' return xml def frameVarsToXML(frame): """ dumps frame variables to XML <var name="var_name" scope="local" type="type" value="value"/> """ # print "Calling frameVarsToXML" xml = "" try: keys = frame.f_locals.keys() keys.sort() for k in keys: v = frame.f_locals[k] xml += varToXML(v, str(k)) except: traceback.print_exc() return xml def findFrame(thread, frame_id): """ returns a frame on the thread that has a given frame_id """ # print "thread is ", str(thread) # print "current thread is", str(threading.currentThread) if thread != threading.currentThread() : raise VariableError("findFrame: must execute on same thread") curFrame = sys._getframe() if frame_id == "*": return curFrame # any frame is specified with "*" lookingFor = int(frame_id) while (curFrame != None and lookingFor != id(curFrame)): curFrame = curFrame.f_back if curFrame == None : raise VariableError("findFrame: frame not found") return curFrame def resolveCompoundVariable(thread, frame_id, scope, attrs): """ returns the value of the compound variable as a dictionary""" frame = findFrame(thread, frame_id) attrList = attrs.split('\t') if (scope == "GLOBAL"): var = frame.f_globals del attrList[0] # globals are special, and they get a single dummy unused attribute else: var = frame.f_locals for k in attrList: print >>sys.stderr, "resolving ", k print >>sys.stderr, "attribute is ", k (type, typeName, resolver) = getType(var) var = resolver.resolve(var, k) print >>sys.stderr, "Got variable", var (type, typeName, resolver) = getType(var) return resolver.getDictionary(var) |