📄 phpdebugger.py
字号:
def stopLsnr(self): if not self.lsnrThr: return # # Then we try to stop our listener thread. # if self.lsnrThr.hasBeenConnected(): # # If the listener thread has already accepted a connection from a # php debug module/client, it is sleeping now and wait for this # condition object to be set so that it can exit. # self.setLsnrAction(PHPDebuggerCallback.ACTION_STOP) self.actionEvent.set() else: # # If the listener thread has never been connected from a php debug # module/client, it is still blocking on a accept() call. We # connect to it here and send a special shutdown command asking it # to exit. # shutdownMessage = IntToC4(DBG_SYNC) + IntToC4(DBGC_AG_SHUTDOWN_REQ) + IntToC4(0) + IntToC4(0) tempSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: tempSocket.connect((self.lsnrHost, self.lsnrPort)) tempSocket.sendall(shutdownMessage) except: myprint("shutdown connection/send message got exception!") tempSocket.close() self.lsnrThr.join() self.lsnrThr = Noneclass PHPDBGLsnrThr(threading.Thread): def __init__(self, interfacei, hosti, porti, actionEventi, uii): threading.Thread.__init__(self) self.interface = interfacei self.svrHost = hosti self.svrPort = porti self.actionEvent = actionEventi self.svrSocket = None self.clntConn = None self.clntAddr = None self.nonBlockingTimeout = 1 self.connHeader = None self.ui = uii def initSvrSocket(self): self.svrSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.svrSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.svrSocket.bind((self.svrHost, self.svrPort)) def waitForClntConn(self): self.svrSocket.listen(5) self.clntConn, self.clntAddr = self.svrSocket.accept() self.clntConn.settimeout(self.nonBlockingTimeout) def run(self): # # Initialize this server socket. # self.initSvrSocket() while True: # # Block until we get a new connection from a php debug client or our # debugger ui (with a special shutting down header/command). # self.waitForClntConn() # # Ok, a new connection comes in ... Read the header to see where it # comes from. # self.connHeader = ResponseHeader(self) if self.connHeader.command == DBGC_AG_SHUTDOWN_REQ: # # This is a special command coming from our UI asking this # thread to exit. This only happens if after this thread has # been waiting for new connections from PHP debug module, no one # connects, and UI is ready to shutdown this thread. # self.shutdown() break else: # # Tell the main gui thread to handle this new connection. # wx.CallAfter(self.interface.newConnEventHandler) # # From now on, PHPDebuggerCallback will communicate with the php # debug module using this thread's clntConn socket. This thread # itself will keep sleeping until get notified to make some # actions. # self.actionEvent.wait() self.actionEvent.clear() action = self.interface.getLsnrAction() if action == PHPDebuggerCallback.ACTION_STOP: self.shutdown() break elif action == PHPDebuggerCallback.ACTION_LISTEN: if self.clntConn: self.clntConn.shutdown(socket.SHUT_RDWR) self.clntConn.close() self.clntConn = None continue else: continue def shutdown(self): # # Cleanup and ready to exit. # self.clntConn.shutdown(socket.SHUT_RDWR) self.clntConn.close() self.svrSocket.close() def recv(self, size, blocking = False): if self.clntConn: myprint("recv: trying to receive %d bytes of data ...", size) if blocking: self.clntConn.settimeout(None) else: self.clntConn.settimeout(self.nonBlockingTimeout) try: rData = self.clntConn.recv(size) except socket.timeout: myprint("recv: got timed out") rData = None except: myprint("recv: got an unexpected exception: %s", sys.exc_info()[0]) raise PHPDBGConnException return rData else: raise PHPDBGConnException def sendall(self, message): if self.clntConn: try: self.clntConn.sendall(message) except: myprint("sendall: got an unexpected exception: %s", sys.exc_info()[0]) raise PHPDBGConnException else: raise PHPDBGConnException def hasBeenConnected(self): return self.clntConn != None def getConnHeader(self): return self.connHeaderclass PHPValue(object): PEV_NAMES = ("undefined", "long", "double", "string", "array", "object", "boolean", "resource", "reference", "soft reference", "null") PEVT_UNKNOWN = 0 PEVT_LONG = 1 PEVT_DOUBLE = 2 PEVT_STRING = 3 PEVT_ARRAY = 4 PEVT_OBJECT = 5 PEVT_BOOLEAN = 6 PEVT_RESOURCE = 7 PEVT_REF = 8 PEVT_SOFTREF = 9 PEVT_NULL = 10 NULL_VALUE_STR = "NULL" TRUE_VALUE_STR = "True" FALSE_VALUE_STR = "False" OBJECT_VALUE_STR = "<%s> object" STRING_VALUE_STR = "\"%s\"" REFERENCE_VALUE_STR = "<reference><%s>" RESOURCE_VALUE_STR = "<%s><%s>" def __init__(self, frame, type, valueList): self.fStackFrame = frame self.fValueType = type if type == self.PEVT_OBJECT: self.fValueString = self.OBJECT_VALUE_STR % valueList[0] self.fVariables = valueList[1:] elif type == self.PEVT_ARRAY: self.fValueString = '' self.fVariables = valueList else: self.fVariables = [] if type == self.PEVT_STRING: self.fValueString = self.STRING_VALUE_STR % valueList[0] elif type == self.PEVT_NULL: self.fValueString = self.NULL_VALUE_STR elif type == self.PEVT_BOOLEAN: if valueList[0] == "0": self.fValueString = self.FALSE_VALUE_STR else: self.fValueString = self.TRUE_VALUE_STR elif type == self.PEVT_REF or type == self.PEVT_SOFTREF: self.fValueString = self.REFERENCE_VALUE_STR % valueList[0] elif type == self.PEVT_RESOURCE: self.fValueString = self.RESOURCE_VALUE_STR % (valueList[0], valueList[1]) else: self.fValueString = valueList[0] def addVariable(self, item): if item != None: self.fVariables.append(item) return self.fVariables def setParent(self, parent): if self.fVariables != None and len(self.fVariables) > 0: for item in self.fVariables: item.setParent(parent) def getReferenceType(self): return self.fValueType def getReferenceTypeName(self): return self.PEV_NAMES[self.fValueType] def setReferenceType(self, type): self.fValueType = type def getValueString(self): return self.fValueString def getChildrenVariables(self): return self.fVariables def hasVariables(self): return len(self.fVariables) > 0 def childrenIsSortable(self): # # TODO: if self.fValueType != self.PEVT_ARRAY: # return Trueclass PHPVariable(object): def __init__(self, frame, parent, valueType, name, valueList): self.fStackFrame = frame self.fName = None self.fLongName = None self.fPureName = None self.fValue = PHPValue(frame, valueType, valueList) self.fParent = parent self.setName(name) self.setChildrensParent(valueList) def setName(self, name): self.fPureName = name type = self.getReferenceType() if type == PHPValue.PEVT_ARRAY: numItems = len(self.getChildrenVariables()) self.fName = name + "[" + str(numItems) + "]" else: self.fName = name if not self.fParent or self.fParent.getName() == None: self.fLongName = name else: self.setLongName() return def setLongName(self): parentType = self.fParent.getReferenceType() if parentType == PHPValue.PEVT_ARRAY: self.fLongName = self.fParent.getLongName() + "['" + self.fPureName + "']" elif parentType == PHPValue.PEVT_OBJECT: self.fLongName = self.fParent.getLongName() + "." + self.fName else: self.fLongName = self.fName return def getValue(self): return self.fValue def getValueString(self): return self.fValue.getValueString() def getChildrenVariables(self): return self.fValue.getChildrenVariables() def getName(self): return self.fName def getParent(self): return self.fParent def setParent(self, parent): self.fParent = parent self.setLongName() return def setChildrensParent(self, childrenList): if self.fValue.hasVariables(): for child in self.fValue.getChildrenVariables(): child.setParent(self) def getLongName(self): return self.fLongName def getReferenceTypeName(self): return self.fValue.getReferenceTypeName() def getReferenceType(self): return self.fValue.getReferenceType() def setReferenceType(self, type): tp = self.getValue.setReferenceType(type) return tp def setValue(self, expression): if self.fValue.getReferenceType() == PHPValue.PEVT_STRING: evalString = self.fLongName + "=\"" + expression + "\"" else: evalString = self.fLongName + "=" + expression vars = self.fStackFrame.getPHPDBGInterface().evalBlock(self.fStackFrame, evalString) self.fValue = vars[0].fValue def toString(self): rtype = self.getReferenceType() if rtype == PHPValue.PEVT_ARRAY: elements = len(self.fValue.getChildrenVariables()) if elements == 0: tmpStr = self.getName() + " [no elements]" elif elements == 1: tmpStr = self.getName() + " [1 element]" else: tmpStr = self.getName() + " [" + str(elements) + " elements]" elif rtype == PHPValue.PEVT_OBJECT: tmpStr = self.getName() + " [ class: " + self.fValue.getValueString() + "]" elif rtype == PHPValue.PEVT_STRING: tmpStr = self.getName() + " = \"" + self.fValue.getValueString() + "\"" else: tmpStr = self.getName() + " = " + self.fValue.getValueString() return tmpStr def hasChildren(self): return self.fValue.hasVariables() def childrenIsSortable(self): return self.fValue.childrenIsSortable()class PHPStackFrame(object): def __init__(self, interface, file, line, frameIndex, scopeId, desc, modNum): self.interface = interface self.fileName = file self.lineNo = line self.frameIndex = frameIndex self.scopeId = scopeId self.desc = desc self.modNum = modNum self.variables = [] self.shortFileName = None self.shortDesc = None self.displayStr = None self.longDisplayStr = None self._getFileNamesAndShortDesc() myprint("PHPStackFrame::__init__(): new PHPStackFrame: file=%s, lineNo=%s, frameIndex=%s, scopeId=%s, desc=%s, modNum=%s, shortFileName=%s, shortDesc=%s", (repr(file), repr(line), repr(frameIndex), repr(scopeId), repr(desc), repr(modNum), repr(self.shortFileName), repr(self.shortDesc))) def _getFileNamesAndShortDesc(self): tmp = [] if self.desc: tmp = self.desc.split("::") if self.fileName: self.shortFileName = os.path.basename(self.fileName)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -