Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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)