def __init__(self, do): QObject.__init__(self) self.ptyhandler = PtyHandler() self.do = do self.connector = self.do.gdb_connector self.signalProxy = self.do.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() self.connector.start() self.connector.reader.asyncRecordReceived.connect(self.handleAsyncRecord, Qt.QueuedConnection) self.__config = DebugConfig() self.do.configStore.registerConfigSet(self.__config) self.__config.itemsHaveChanged.connect(self.updateConfig) self.__binaryWatcher = QFileSystemWatcher() self.__binaryWatcher.fileChanged.connect(self.__binaryChanged) self.do.signalProxy.addProxy(["openExecutable", "run", "setRecord", "next_", "reverse_next", "step", "reverse_step", "cont", "interrupt", "finish", "reverse_finish", "evaluateExpression", "executeCliCommand", "inferiorUntil", "getStackDepth", "selectStackFrame"], self)
def __init__(self, distributedObjects): QObject.__init__(self) self.ptyhandler = PtyHandler() self.distributedObjects = distributedObjects self.connector = self.distributedObjects.gdb_connector self.gdbinit = self.distributedObjects.gdb_init self.signalProxy = self.distributedObjects.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() GDBInit.writeFile(self.gdbinit.getPath(),self.gdbinit.getFileName()) self.connector.start() self.connector.initPrettyPrinter(self.gdbinit.getPath() + self.gdbinit.getFileName()) self.connector.startPrettyPrinting() self.toggleBeautify = True self.connector.reader.asyncRecordReceived.connect(self.handleAsyncRecord, Qt.QueuedConnection) self.__config = DebugConfig() self.distributedObjects.configStore.registerConfigSet(self.__config) self.__config.itemsHaveChanged.connect(self.updateConfig)
def __init__(self, do): QObject.__init__(self) self.ptyhandler = PtyHandler() self.do = do self.connector = self.do.gdb_connector self.signalProxy = self.do.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() self.connector.start() self.connector.reader.asyncRecordReceived.connect(self.handleAsyncRecord, Qt.QueuedConnection) self.__config = DebugConfig() self.do.configStore.registerConfigSet(self.__config) self.__config.itemsHaveChanged.connect(self.updateConfig) self.__binaryWatcher = QFileSystemWatcher() self.__binaryWatcher.fileChanged.connect(self.__binaryChanged)
def __init__(self, distributedObjects): QObject.__init__(self) self.settings = QSettings("fh-hagenberg", "SysCDbg") self.ptyhandler = PtyHandler() self.distributedObjects = distributedObjects self.connector = self.distributedObjects.gdb_connector self.editorController = self.distributedObjects.editorController self.breakpointController = self.distributedObjects.breakpointController self.signalProxy = self.distributedObjects.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() self.connector.start() QObject.connect(self.connector.reader, SIGNAL('asyncRecordReceived(PyQt_PyObject)'), self.handleAsyncRecord, Qt.QueuedConnection)
def __init__(self, distributedObjects): QObject.__init__(self) self.ptyhandler = PtyHandler() self.distributedObjects = distributedObjects self.connector = self.distributedObjects.gdb_connector self.signalProxy = self.distributedObjects.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() self.connector.start() self.connector.reader.asyncRecordReceived.connect(self.handleAsyncRecord, Qt.QueuedConnection) self.__config = DebugConfig() self.distributedObjects.configStore.registerConfigSet(self.__config) self.__config.itemsHaveChanged.connect(self.updateConfig)
class DebugController(QObject): executableOpened = pyqtSignal('PyQt_PyObject') def __init__(self, distributedObjects): QObject.__init__(self) self.ptyhandler = PtyHandler() self.distributedObjects = distributedObjects self.connector = self.distributedObjects.gdb_connector self.breakpointController = self.distributedObjects.breakpointController self.signalProxy = self.distributedObjects.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() self.connector.start() self.connector.reader.asyncRecordReceived.connect(self.handleAsyncRecord, Qt.QueuedConnection) self.__config = DebugConfig() self.distributedObjects.configStore.registerConfigSet(self.__config) self.__config.itemsHaveChanged.connect(self.updateConfig) def updateConfig(self): if self.executableName: logging.warning("Please reload executable for changes to take effect!") def openExecutable(self, filename): # make sure we only open absolute paths, otherwise eg. RecentFileHandler # will not know _where_ the file was we opened and store different # relative paths for the same file filename = os.path.abspath(filename) if not os.path.exists(filename): logging.error("File %s was not found.", filename) return if self.distributedObjects.editorController.closeOpenedFiles(): # closing source files may be canceled by user if self.executableName != None: #clear variables, tracepoints, watches,... by connecting to this signal self.signalProxy.emitCleanupModels() self.connector.changeWorkingDirectory(os.path.dirname(filename)) self.connector.openFile(filename) if self.__config.breakAtMain.value: self.distributedObjects.breakpointController.insertBreakpoint("main", None) self.executableOpened.emit(filename) self.executableName = filename def run(self, args=None): self.connector.setTty(self.ptyhandler.ptyname) self.connector.setArgs(args) self.connector.run() self.lastCmdWasStep = False self.signalProxy.emitRunClicked() def record_start(self): self.connector.record_start() def record_stop(self): self.connector.record_stop() def next_(self): self.connector.next_() self.lastCmdWasStep = True def reverse_next(self): self.connector.reverse_next() self.lastCmdWasStep = True def step(self): self.connector.step() self.lastCmdWasStep = True def reverse_step(self): self.connector.reverse_step() self.lastCmdWasStep = True def cont(self): self.connector.cont() self.lastCmdWasStep = False def interrupt(self): self.connector.interrupt() self.lastCmdWasStep = False def finish(self): self.connector.finish() self.lastCmdWasStep = False def until(self, file_, line): self.connector.until(file_, line) self.lastCmdWasStep = False def evaluateExpression(self, exp): if exp == "": return None exp = exp.replace('"', '\"') return self.connector.evaluate("\"" + exp + "\"") def executeCliCommand(self, cmd): return self.connector.executeCliCommand(cmd) def handleAsyncRecord(self, rec): if rec.type_ == GdbOutput.EXEC_ASYN: if rec.class_ == GdbOutput.STOPPED: self.handleStoppedRecord(rec) elif rec.class_ == GdbOutput.RUNNING: self.signalProxy.emitInferiorIsRunning(rec) elif rec.type_ == GdbOutput.NOTIFY_ASYN: if rec.class_ == GdbOutput.THREAD_CREATED: self.signalProxy.emitThreadCreated(rec) elif rec.class_ == GdbOutput.THREAD_EXITED: self.signalProxy.emitThreadExited(rec) def handleStoppedRecord(self, rec): # With reverse debugging, some stopped records might not contain a # reason. Predefine it as None, since all unknown reasons will be # handled as the inferior having stopped normally. reason = None for r in rec.results: if r.dest == 'reason': reason = r.src if r.dest == 'frame': frame = r.src if r.dest == 'signal-name': signal_name = r.src if r.dest == 'signal-meaning': signal_meaning = r.src if r.dest == "bkptno": bkptno = int(r.src) if reason in ['exited-normally', 'exited']: self.signalProxy.emitInferiorHasExited(rec) elif reason == 'breakpoint-hit': stop = False tp = self.distributedObjects.tracepointController.model().getTracepointIfAvailable(frame) if self.distributedObjects.breakpointController.model().isBreakpointByNumber(bkptno) or self.lastCmdWasStep: self.signalProxy.emitInferiorStoppedNormally(rec) stop = True self.lastCmdWasStep = False if tp != None: tp.tracePointOccurred(stop) self.distributedObjects.signalProxy.emitTracepointOccurred() elif reason == "signal-received": logging.warning("Signal received: %s (%s) in %s:%s", signal_name, signal_meaning, frame.file, frame.line) self.signalProxy.emitInferiorReceivedSignal(rec) else: self.signalProxy.emitInferiorStoppedNormally(rec) def executePythonCode(self, code): exec(code, {'do': self.distributedObjects}) def inferiorUntil(self): current_opened_file = self.distributedObjects.editorController.editor_view.getCurrentOpenedFile() line, _ = current_opened_file.edit.getCursorPosition() self.until(current_opened_file.filename, line + 1) def getExecutableName(self): return self.executableName def getStackDepth(self): return self.connector.getStackDepth() def selectStackFrame(self, exp): return self.connector.selectStackFrame(exp)
class DebugController(QObject): executableOpened = pyqtSignal('PyQt_PyObject') def __init__(self, do): QObject.__init__(self) self.ptyhandler = PtyHandler() self.do = do self.connector = self.do.gdb_connector self.signalProxy = self.do.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() self.connector.start() self.connector.reader.asyncRecordReceived.connect(self.handleAsyncRecord, Qt.QueuedConnection) self.__config = DebugConfig() self.do.configStore.registerConfigSet(self.__config) self.__config.itemsHaveChanged.connect(self.updateConfig) self.__binaryWatcher = QFileSystemWatcher() self.__binaryWatcher.fileChanged.connect(self.__binaryChanged) def __reloadAction(self): a = QAction("Reload", self) a.triggered.connect(lambda: self.openExecutable(self.executableName)) return a def __binaryChanged(self): """ Slot for FileWatcher - Using QtMessagebox for interaction""" logging.warning("The executable was changed on the disc. Please reload the file.", extra={"actions": [self.__reloadAction()]}) def updateConfig(self): if self.executableName: logging.warning("Configuration changed. Please reload executable for changes to take effect!", extra={"actions": [self.__reloadAction()]}) def openExecutable(self, filename): # make sure we only open absolute paths, otherwise eg. RecentFileHandler # will not know _where_ the file was we opened and store different # relative paths for the same file filename = os.path.abspath(filename) if not os.path.exists(filename): logging.error("File %s was not found.", filename) return if self.do.editorController.closeOpenedFiles(): # closing source files may be canceled by user if self.executableName is not None: # clear variables, tracepoints, watches,... by connecting to this signal self.signalProxy.cleanupModels.emit() self.__binaryWatcher.removePath(self.executableName) self.connector.changeWorkingDirectory(os.path.dirname(filename)) self.connector.openFile(filename) if self.__config.breakAtMain.value: self.do.breakpointModel.insertBreakpoint("main", None) self.executableOpened.emit(filename) self.executableName = filename self.__binaryWatcher.addPath(self.executableName) def run(self, args=None): self.connector.setTty(self.ptyhandler.ptyname) if not args: args = "" self.connector.setArgs(args) try: self.connector.run() self.lastCmdWasStep = False self.signalProxy.runClicked.emit() except GdbError: pass def setRecord(self, state): if state: self.connector.record_start() else: self.connector.record_stop() self.signalProxy.recordStateChanged.emit(state) def next_(self): self.connector.next_() self.lastCmdWasStep = True def reverse_next(self): self.connector.next_(True) self.lastCmdWasStep = True def step(self): self.connector.step() self.lastCmdWasStep = True def reverse_step(self): self.connector.step(True) self.lastCmdWasStep = True def cont(self): self.connector.cont() self.lastCmdWasStep = False def interrupt(self): self.connector.interrupt() self.lastCmdWasStep = False def finish(self): self.connector.finish() self.lastCmdWasStep = False def reverse_finish(self): self.connector.finish(True) self.lastCmdWasStep = False def evaluateExpression(self, exp): if exp == "": return None exp = exp.replace('"', '\"') return self.connector.evaluate("\"" + exp + "\"") def executeCliCommand(self, cmd): return self.connector.executeCliCommand(cmd) def handleAsyncRecord(self, rec): if rec.type_ == GdbOutput.EXEC_ASYN and rec.class_ == GdbOutput.STOPPED: self.handleStoppedRecord(rec) elif rec.type_ == GdbOutput.EXEC_ASYN and rec.class_ == GdbOutput.RUNNING: self.signalProxy.inferiorIsRunning.emit(rec) elif rec.type_ == GdbOutput.NOTIFY_ASYN and rec.class_ == GdbOutput.THREAD_CREATED: self.signalProxy.threadCreated.emit(rec) elif rec.type_ == GdbOutput.NOTIFY_ASYN and rec.class_ == GdbOutput.THREAD_EXITED: self.signalProxy.threadExited.emit(rec) elif rec.type_ == GdbOutput.NOTIFY_ASYN and rec.class_ == GdbOutput.BREAKPOINT_MODIFIED: self.signalProxy.breakpointModified.emit(rec) def handleStoppedRecord(self, rec): # With reverse debugging, some stopped records might not contain a # reason. Predefine it as None, since all unknown reasons will be # handled as the inferior having stopped normally. fields = ["reason", "frame", "signal-name", "signal-meaning", "bkptno", "wpt", "value"] field = defaultdict(None) for r in rec.results: if r.dest in fields: field[r.dest] = r.src if field["reason"] in ['exited-normally', 'exited']: self.signalProxy.inferiorHasExited.emit(rec) elif field["reason"] == 'breakpoint-hit': # Ok, we're kind of frantically trying to cover all bases here. We # cannot simply check for file:line combination reported in the # stopped message, since breakpoints may be set to a certain line # (which GDB also reports back as the line where the breakpoint is # really located), but one of the following lines may be reported in # the stopped message (eg., if the breakpoint is set to a function # header, the line reported here will be the first line of the # function's body). # Therefore, we're checking what was hit using the reported # breakpoint number. However, if the user sets both a breakpoint and # a tracepoint in the same line, only one number will be reported # here, but we need to handle both. Therefore, check the location # where what we found was supposed to be, and check if something # else was supposed to be there too. This still might be a problem # (eg. setting a breakpoint and a tracepoint in the line following # the breakpoint, both of which would cause the program to suspend # on yet another line), but that's about as good as our guessing # currently gets. tp = self.do.tracepointController.model().breakpointByNumber(int(field["bkptno"])) bp = self.do.breakpointModel.breakpointByNumber(int(field["bkptno"])) assert tp or bp # either a TP or a BP must have been hit # now that we have one, check if the other is here too if bp and not tp: tp = self.do.tracepointController.model().breakpointByLocation(bp.fullname, bp.line) elif tp and not bp: bp = self.do.breakpointModel.breakpointByLocation(tp.fullname, tp.line) if tp: # this will cause the variable pool to update all variables self.do.signalProxy.tracepointOccurred.emit() tp.recordData() if self.lastCmdWasStep or bp: self.signalProxy.inferiorStoppedNormally.emit(rec) self.lastCmdWasStep = False else: assert tp # if this was not a breakpoint, it must have been a tracepoint self.connector.cont() elif field["reason"] == "signal-received": logging.warning("Inferior received signal <b>%s</b> (%s) at <b>%s:%s</b>.", field["signal-name"], field["signal-meaning"], field["frame"].file, field["frame"].line) self.signalProxy.inferiorReceivedSignal.emit(rec) elif field["reason"] == "watchpoint-trigger": logging.warning("Watchpoint %s on expression <b>%s</b> triggered; old value: %s, new value: %s.", field["wpt"].number, self.do.breakpointModel.breakpointByNumber(field["wpt"].number).where, field["value"].old, field["value"].new) self.signalProxy.inferiorStoppedNormally.emit(rec) else: self.signalProxy.inferiorStoppedNormally.emit(rec) def executePythonCode(self, code): exec(code, {'do': self.do}) def inferiorUntil(self): current_opened_file = self.do.editorController.editor_view.getCurrentOpenedFile() line, _ = current_opened_file.getCursorPosition() self.connector.until(current_opened_file.filename, line + 1) self.lastCmdWasStep = False def getExecutableName(self): return self.executableName def getStackDepth(self): return self.connector.getStackDepth() def selectStackFrame(self, exp): return self.connector.selectStackFrame(exp)
class DebugController(QObject): def __init__(self, distributedObjects): QObject.__init__(self) self.settings = QSettings("fh-hagenberg", "SysCDbg") self.ptyhandler = PtyHandler() self.distributedObjects = distributedObjects self.connector = self.distributedObjects.gdb_connector self.editorController = self.distributedObjects.editorController self.breakpointController = self.distributedObjects.breakpointController self.signalProxy = self.distributedObjects.signalProxy self.executableName = None self.lastCmdWasStep = False self.ptyhandler.start() self.connector.start() QObject.connect(self.connector.reader, SIGNAL('asyncRecordReceived(PyQt_PyObject)'), self.handleAsyncRecord, Qt.QueuedConnection) def openExecutable(self, filename): # die if the file does not exist or has been provided without at least a # relative path; files without a path work with pythons os.* functions # but fail in gdb, so do an extra check for those if not os.path.exists(filename) or os.path.dirname(filename) == "": logging.error("File %s was not found." % filename) return if self.editorController.closeOpenedFiles(): #closing source files may be canceled by user if self.executableName != None: #clear variables, tracepoints, watches,... by connecting to this signal self.signalProxy.emitCleanupModels() self.connector.changeWorkingDirectory(os.path.dirname(filename)) self.connector.openFile(filename) self.emit(SIGNAL('executableOpened'), filename) self.executableName = filename def run(self): self.connector.setTty(self.ptyhandler.ptyname) self.connector.run() self.lastCmdWasStep = False self.signalProxy.emitRunClicked() def next_(self): self.connector.next_() self.lastCmdWasStep = True def step(self): self.connector.step() self.lastCmdWasStep = True def cont(self): self.connector.cont() self.lastCmdWasStep = False def interrupt(self): self.connector.interrupt() self.lastCmdWasStep = False def finish(self): self.connector.finish() self.lastCmdWasStep = False def until(self, file_, line): self.connector.until(file_, line) self.lastCmdWasStep = False def evaluateExpression(self, exp): if exp == "": return None exp = exp.replace('"', '\"') return self.connector.evaluate("\"" + exp + "\"") def executeCliCommand(self, cmd): return self.connector.executeCliCommand(cmd) def handleAsyncRecord(self, rec): if rec.type_ == GdbOutput.EXEC_ASYN: if rec.class_ == GdbOutput.STOPPED: self.handleStoppedRecord(rec) elif rec.class_ == GdbOutput.RUNNING: self.signalProxy.emitInferiorIsRunning(rec) def handleStoppedRecord(self, rec): for r in rec.results: if r.dest == 'reason': reason = r.src if r.dest == 'frame': frame = r.src if r.dest == 'signal-name': signal_name = r.src if r.dest == 'signal-meaning': signal_meaning = r.src if r.dest == 'frame': frame = r.src if r.dest == "bkptno": bkptno = int(r.src) if reason in ['exited-normally', 'exited']: self.signalProxy.emitInferiorHasExited(rec) elif reason == 'breakpoint-hit': stop = False tp = self.distributedObjects.tracepointController.model().getTracepointIfAvailable(frame) if self.distributedObjects.breakpointController.model().isBreakpointByNumber(bkptno) or self.lastCmdWasStep: self.signalProxy.emitInferiorStoppedNormally(rec) stop = True self.lastCmdWasStep = False if tp != None: tp.tracePointOccurred(stop) self.distributedObjects.signalProxy.emitTracepointOccurred() elif reason == "signal-received": logging.warning("Signal received: %s (%s) in %s:%s", signal_name, signal_meaning, frame.file, frame.line) self.signalProxy.emitInferiorReceivedSignal(rec) else: self.signalProxy.emitInferiorStoppedNormally(rec) def executePythonCode(self, code): exec(code, {'do': self.distributedObjects}) def inferiorUntil(self): current_opened_file = self.editorController.editor_view.getCurrentOpenedFile() line, _ = current_opened_file.edit.getCursorPosition() self.until(current_opened_file.filename, line + 1) def getExecutableName(self): return self.executableName def getStackDepth(self): return self.connector.getStackDepth() def selectStackFrame(self, exp): return self.connector.selectStackFrame(exp)