⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phpdebugger.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 5 页
字号:
        elif (cause == None):
            Exception.__init__(self, msg)
        else:
            Exception.__init__(self, "PHPDBGException: message:%s\n, cause:%s" % (msg, cause))


class PHPDBGConnException(PHPDBGException):
    pass


class PHPDebuggerCallback(object):
    ACTION_NONE              = 0
    ACTION_STOP              = 1
    ACTION_LISTEN            = 2

    def __init__(self, ui, service, lsnrHosti, lsnrPorti):
        self.ui              = ui
        self.service         = service
        self.lsnrHost        = lsnrHosti
        self.lsnrPort        = lsnrPorti
        self.lsnrThr         = None
        self.lsnrAction      = PHPDebuggerCallback.ACTION_NONE
        self.clearInternals()
        self.initLsnrThr()


    ############################################################################
    #                      Public callback functions begin
    #
    def Start(self):
        self.lsnrThr.start()

    def ShutdownServer(self, stopLsnr = True):
        #
        # First to tell php debugger to stop execution of the current PHP
        # program.  Disconnect with php dbg module too.
        #
        self.stopPhpDbg()

        #
        # Stop debug listener.
        #
        if stopLsnr:
            self.stopLsnr()

    def BreakExecution(self):
        reqPacket = PHPDBGPacket(IntToC4(DBGC_PAUSE))

        try:
            reqPacket.sendPacket(self.lsnrThr)
            self.awaitAndHandleResponse()
        except PHPDBGConnException:
            self.currConnFinished()
            return

        self.ui.LoadPHPFramesList(self.stackList)
        return

    def SingleStep(self):
        reqPacket = PHPDBGPacket(DBGA_STEPINTO)

        try:
            reqPacket.sendPacket(self.lsnrThr)
            self.lastCommand = DBGA_STEPINTO
            self.awaitAndHandleResponse(blocking = True)
        except PHPDBGConnException:
            self.currConnFinished()
            return

        self.ui.LoadPHPFramesList(self.stackList)
        return

    def Next(self):
        reqPacket = PHPDBGPacket(DBGA_STEPOVER)

        try:
            reqPacket.sendPacket(self.lsnrThr)
            self.lastCommand = DBGA_STEPOVER
            self.awaitAndHandleResponse(blocking = True)
        except PHPDBGConnException:
            self.currConnFinished()
            return

        self.ui.LoadPHPFramesList(self.stackList)
        return

    def Continue(self):
        reqPacket = PHPDBGPacket(DBGA_CONTINUE)

        try:
            reqPacket.sendPacket(self.lsnrThr)
            self.lastCommand = DBGA_CONTINUE
            self.awaitAndHandleResponse(blocking = True)
        except PHPDBGConnException:
            self.currConnFinished()
            return

        self.ui.LoadPHPFramesList(self.stackList)
        return

    def Return(self):
        reqPacket = PHPDBGPacket(DBGA_STEPOUT)

        try:
            reqPacket.sendPacket(self.lsnrThr)
            self.lastCommand = DBGA_STEPOUT
            self.awaitAndHandleResponse(blocking = True)
        except PHPDBGConnException:
            self.currConnFinished()
            return

        self.ui.LoadPHPFramesList(self.stackList)
        return

    def PushBreakpoints(self, noRemove = False):
        tmpList = []
        bps     = self.service.GetMasterBreakpointDict()
        for fileName in bps.keys():
            if fileName.endswith('.php'):
                lines = bps[fileName]
                if lines:
                    for lineNo in lines:
                        if lineNo:
                            #
                            # A tuple (fileName, lineNo) is an item which is
                            # used as a key in self.bpDict.
                            #
                            tmpList.append(self.createBpKey(fileName, lineNo))
                            myprint("PushBreakpoints(): global breakpoint \'%s:%i\'", (fileName, lineNo))

        #
        # Check to see if we have any new breakpoints added.
        #
        for oneKey in tmpList:
            if not self.bpDict.has_key(oneKey):
                #
                # A new breakpoint.
                #
                newBp = BreakPoint(self, oneKey[0], oneKey[1])
                newBp.addSelf()
                self.bpDict[oneKey] = newBp
                myprint("PushBreakpoints(): newly added global breakpoint \'%s:%i\'", (oneKey[0], oneKey[1]))

        if noRemove:
            return

        #
        # Check to see if any bp that is in our list, but not in the latest
        # global list.  If so, it must have been removed recently in the
        # global one.  Remove it from our list and tell php debugger to do
        # so as well.
        #
        toRemoveList = []
        for oneKey in self.bpDict.keys():
            if tmpList.count(oneKey) == 0:
                toRemoveList.append((oneKey, self.bpDict[oneKey]))
                myprint("PushBreakpoints(): recently removed global breakpoint \'%s:%i\'", (oneKey[0], oneKey[1]))

        for bp in toRemoveList:
            bp[1].removeSelf()
            del self.bpDict[bp[0]]
            myprint("PushBreakpoints(): successfully removed breakpoint \'%s:%i\' from both our local list and php debugger", (bp[0][0], bp[0][1]))

        return
    #
    #                      Public callback functions end
    ############################################################################


    def newConnEventHandler(self):
        #
        # Ok, we've got a connection from the php debugger, and some initial
        # frame data from it.  Everything is ready and let's make some initial
        # actions.
        #
        self.clearInternals()

        try:
            self.awaitAndHandleResponse(self.lsnrThr.getConnHeader())
        except PHPDBGConnException:
            self.currConnFinished()
            return

        self.PushBreakpoints(True)
        self.ui.LoadPHPFramesList(self.stackList)

    #
    # This could be called when this object is constructed or when self is
    # re-initialized after getting a new dbg module connection as a new
    # session.
    #
    def clearInternals(self):
        self.stackList       = []
        self.errStackList    = []
        self.stackFrameIndex = 0
        self.isErrStack      = False
        self.errStr          = ''
        self.modList         = []
        self.stopOnError     = True
        self.lastCommand     = None
        self.evalRet         = ''
        self.modDict         = {}
        self.bpDict          = {}
        self.rawDataDict     = {}
        self.sessID          = 0
        self.sessType        = 0
        self.sessEnded       = False
        self.frameCounter    = 1000
        self.variableList    = []
        self.verMajor        = 0
        self.verMinor        = 0
        self.verDesc         = None

    def initLsnrThr(self):
        self.actionEvent = threading.Event()
        self.lsnrThr     = PHPDBGLsnrThr(self, self.lsnrHost, self.lsnrPort, self.actionEvent, self.ui)

    def awaitAndHandleResponse(self, header = None, blocking = False, disable = True, stopping = False):
        if disable:
            self.ui.DisableWhileDebuggerRunning()

        while self.readResponse(header, blocking) != 0:
            myprint("Waiting for response")

        if stopping:
            self.ui.DisableAfterStop()
        else:
            self.ui.EnableWhileDebuggerStopped()

    def requestDBGVersion(self):
        #TODO: necessary?
        pass

    def getSourceTree(self):
        #TODO: necessary?
        pass

    def addDBGModName(self):
        #TODO: necessary?
        pass

    def getNextFrameCounter(self):
        self.frameCounter = self.frameCounter + 1
        return self.frameCounter

    def getVariables(self, stack):
        self.variableList = []

        reqPacket = PHPDBGPacket(DBGA_REQUEST)
        reqFrame  = PHPDBGFrame(FRAME_EVAL)

        reqFrame.addInt(0)
        reqFrame.addInt(stack.getFrameScopeId())
        reqPacket.addFrame(reqFrame)
        myprint("PHPDebuggerCallback::getVariables(): about to send eval request")

        try:
            reqPacket.sendPacket(self.lsnrThr)
            self.awaitAndHandleResponse(disable = False)
        except PHPDBGConnException:
            self.currConnFinished()
            return self.variableList

        myprint("PHPDebuggerCallback::getVariables(): evalRet=%s", self.evalRet)
        evalStr = PHPDBGEvalString(stack, self.evalRet)
        if evalStr:
            self.variableList = evalStr.getVars()
        myprint("PHPDebuggerCallback::getVariables(): about to return")

        return self.variableList

    def evalBlock(self, stack, evalStr):
        reqPacket = PHPDBGPacket(DBGA_REQUEST)
        reqFrame1 = PHPDBGFrame(FRAME_EVAL)
        reqFrame2 = PHPDBGFrame(FRAME_RAWDATA)

        frameID = self.getNextFrameCounter()
        reqFrame1.addInt(frameID)
        reqFrame1.addInt(1)

        reqFrame2.addInt(frameID)
        reqFrame2.addInt(len(evalStr) + 1)
        reqFrame2.addStr(evalString)

        reqPacket.addFrame(reqFrame2)
        reqPacket.addFrame(reqFrame1)

        try:
            reqPacket.sendPacket(self.lsnrThr)
            self.awaitAndHandleResponse(disable = False)
        except PHPDBGConnException:
            self.currConnFinished()
            return None

        evalStr = PHPDBGEvalString(stack, self.evalRet)

        return evalStr.getVars()

    def getBPUnderHit(self):
        for bp in self.bpDict.values():
            if bp.isUnderHit():
                return bp

        return None

    def getRawFrameData(self, frameNo):
        if self.rawDataDict.has_key(frameNo):
            #
            # Once the frameData is consumed, remove it from rawDataDict.
            #
            return self.rawDataDict.pop(frameNo)
        else:
            #
            # TODO: do we need to handle the case when the raw frame data hasn't
            # been received before?
            #
            return None

    def getModByNum(self, modNum):
        if self.modDict.has_key(modNum):
            return self.modDict[modNum]
        else:
            return None

    def getModByFileName(self, fileName):
        for mn, fn in self.modDict.iteritems():
            if fn == fileName:
                return mn

        return 0

    def setMod(self, modNum, fileName):
        if modNum != 0 and fileName:
            self.modDict[modNum] = fileName

        return

    def readResponse(self, headeri = None, blockingi = False):
        inHeader        = headeri
        header          = None
        cmdReceived     = 0
        isFirstPacket   = True
        blocking        = blockingi
        self.isErrStack = False
        self.rawDataDict.clear()

        while True:
            #
            # If we have already received the first packet, we can't block any
            # more.
            #
            if not isFirstPacket:
                blocking = False

            #
            # If this is the first loop and we have a non-empty header passed in, use it.  Otherwise,
            # read in a new header.  For subsequent loops, inHeader is None so we always read a new
            # header from the wire.
            #
            if inHeader:
                header   = inHeader
                inHeader = None
            else:
                header   = ResponseHeader(self.lsnrThr, blocking)

            if not header.isValid:
                return 0

            cmdReceived = header.command
            frame       = ResponsePacketFrame(self.lsnrThr, header.toRead, None, blocking)
            if not frame.isValid:
                return 0

            isFirstPacket     = False
            isFirstStackFrame = True
            while frame and frame.isValid:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -