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
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)))
def disconnect(self): gdb.post_event(gdbCommands.Executor("disconnect"))
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")
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
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)))