예제 #1
0
 def cleanup(self, died=False):
     """This is the last function that should run before the program closes"""
     # pause the target
     if not self.silent:
         print("Cleaning up program...")
     self.stopThreads = True
     try:
         gdb.events.stop.disconnect(gdbHandlers.stop_handler)
         gdb.events.cont.disconnect(gdbHandlers.cont_handler)
         gdb.events.exited.disconnect(gdbHandlers.exited_handler)
         if not died:
             gdb.post_event(gdbCommands.Executor("interrupt"))
             gdb.post_event(gdbCommands.Executor("disconnect"))
         gdb.post_event(gdbCommands.Executor("set confirm off"))
         gdb.post_event(gdbCommands.Executor("quit"))
     except (gdb.GdbError, gdb.error) as e:
         if not self.silent:
             print(e)
     if not self.silent:
         print("Done!\n")
     self.sendResponseMsg(strings.finishedMsg)
     time.sleep(0.01)
     return
예제 #2
0
 def reconnect(self):
     time.sleep(0.01)
     # first one is to trigger an error and get it to disconnect, so we ignore error output
     gdb.post_event(gdbCommands.Executor("target remote :{}".format(self.gdbPortNum), i=True))
     gdb.post_event(gdbCommands.Executor("target remote :{}".format(self.gdbPortNum)))
예제 #3
0
 def disconnect(self):
     gdb.post_event(gdbCommands.Executor("disconnect"))
예제 #4
0
    def socketServer(self):
        """Handle all of the commands that come to the GDB instance.

        This function will be run in a separate thread so that the GDB instance
        running underneath will be able to execute commands.
        """

        # set up socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            sock.bind((socket.gethostname(), self.pythonPortNum))
        except OSError as oe:
            print("Failed binding with error number {}".format(oe.errno))
            # Since this socket was how we were going to communicate with the supervisor,
            #  just return here and wait for the supervisor to notice the timeout
            return
        sock.settimeout(5)
        sock.listen(1)

        # try to connect 5 times
        for t in range(1, 6):
            try:
                self.socketResponse, address = sock.accept()
                break
            except socket.timeout:
                if t == 5:
                    print("Error, could not accept socket connection in GDB socket server",
                            file=sys.stderr)
                else:
                    time.sleep(0.1*t)

        sendStr = "Opening socket on port " + str(sock.getsockname())
        self.sendResponseMsg(sendStr)
        sendStr = "Connection from: " + str(address)
        self.sendResponseMsg(sendStr)

        # service commands sent
        msg = ""
        while True:
            try:
                data = network.recv_msg(self.socketResponse)
                data = data.decode('utf-8')
            except ConnectionError:
                print("GDB client side socket error!", file=sys.stderr)
            except AttributeError as ae:
                print(ae)
                print("Could not decode: `{}`".format(data))
                continue
            if not data:
                print("GDB Error: Ran out of data to decode!")
                break

            # debug printing
            if self.debug:
                print("SERVER: " + data, file=sys.stderr)

            ##################### configuring ######################
            if data == strings.configGdbCmd:
                self.configure()
                msg = strings.configGdbMsg
            elif data == strings.silentConfigCmd:
                self.silent = True
                self.configure()
                self.silent = False

            elif data == strings.setTimeoutCmd:
                runtime = network.recv_msg(self.socketResponse).decode('utf-8')
                self.setTimeout(float(runtime))
                msg = strings.setTimeoutMsg
            elif data == strings.handlerSetupCmd:
                msg = strings.handlerSetupMsg
                self.setUpHandlers()

            # talking to the Qemu instance
            elif data == strings.disconnectCmd:
                self.disconnect()
                continue
            elif data == strings.reconnectCmd:
                self.reconnect()
                continue
            
            ##################### control flow #####################
            elif data.startswith(strings.contCmd):
                if not data == strings.contCmd:
                    try:
                        contCount = int(data.split(maxsplit=1)[1])
                    except (ValueError, TypeError):
                        contCount = 1
                else:
                    contCount = 1
                gdbCommands.continueDebug(contCount)
                # no response
                continue
            elif data == strings.quitCmd:
                self.sendResponseMsg(strings.quitMsg)
                self.finished = True
                self.cleanup()
                break
            elif data == strings.killGdbCmd:
                self.sendResponseMsg(strings.killGdbMsg)
                self.cleanup(True)
                break
            elif data == strings.silentKillCmd:
                self.sendResponseMsg(strings.killGdbMsg)
                self.silent = True
                self.cleanup(True)
                break
            elif data == strings.reloadCmd:
                self.reloadExecutable()
                # no response
                continue
            elif data == strings.interruptCmd:
                gdb.post_event(gdbCommands.Executor("interrupt", p=True))
                print(self.cmdRespQ.get())
                time.sleep(0.01)
                # get the string to make sure it completes before 
                #  continuing, but don't return it
                continue
            
            ##################### read values ######################
            # variables
            elif data == strings.getVarCmd:
                varName = network.recv_msg(self.socketResponse).decode('utf-8')
                if self.debug:
                    print(" reading {}".format(varName))
                msg = gdbCommands.getVariable(varName)
            elif data == strings.readGlblTimerCmd:
                msg = self.readGlobalTimer()

            # registers
            elif data == strings.readRegCmd:
                regName = network.recv_msg(self.socketResponse).decode('utf-8')
                if self.debug:
                    print(" reading {}".format(regName))
                regVal = gdbCommands.readReg(regName)
                msg = regVal
            elif data == strings.readMemCmd:
                addr = network.recv_msg(self.socketResponse).decode('utf-8')
                if self.debug:
                    print(" reading {}".format(addr))
                # return the value and name of the variable being read
                memVal = gdbCommands.readMem(addr)
                msg = memVal

            # memory addresses
            elif data == strings.regNameCmd:
                regName = network.recv_msg(self.socketResponse).decode('utf-8')
                memName = gdbCommands.getNameReg(regName)
                msg = memName if memName is not None else "None"
            elif data == strings.memNameCmd:
                addr = network.recv_msg(self.socketResponse).decode('utf-8')
                memName = gdbCommands.getNameMem(addr)
                msg = memName if memName is not None else "None"
            elif data == strings.symbolAddrCmd:
                name = network.recv_msg(self.socketResponse).decode('utf-8')
                memAddr = gdbCommands.getSymAddr(name)
                msg = str(memAddr) if memAddr is not None else "None"

            # arbitrary command
            elif data == strings.gdbExecCmd:
                # other side responsible for decoding the information
                cmdStr = network.recv_msg(self.socketResponse).decode('utf-8')
                msg = gdbCommands.execCmd(cmdStr)
            
            ##################### write values #####################
            elif data == strings.writeRegCmd:
                regName = network.recv_msg(self.socketResponse).decode('utf-8')
                regVal = network.recv_msg(self.socketResponse).decode('utf-8')
                gdbCommands.writeReg(regName, regVal)
                continue
            elif data == strings.writeMemCmd:
                addr = network.recv_msg(self.socketResponse).decode('utf-8')
                memVal = network.recv_msg(self.socketResponse).decode('utf-8')
                gdbCommands.writeMem(addr, memVal)
                continue
            # otherwise, unrecognized command
            else:
                msg = "invalid command: " + data
            self.sendResponseMsg(msg)

        if not self.silent:
            print("GDB instance closed")
예제 #5
0
 def readGlobalTimer(self):
     """Read the value of the Zynq A9 global timer."""
     gdb.post_event(gdbCommands.Executor("call (void)XTime_GetTime(&{})".format(strings.tProbeName)))
     timerVal = gdbCommands.getVariable(strings.tProbeName)
     return timerVal
예제 #6
0
 def reloadExecutable(self):
     """Reloads the ELF file and resets the PC."""
     gdb.post_event(gdbCommands.Executor("file {}".format(self.fileName)))
     gdb.post_event(gdbCommands.Executor("set $pc = {}".format(self.resetPCval)))