Example #1
0
class GDBServer(Thread):
    def __init__(self,process):
        Thread.__init__(self)
        self.working = True
        self.cmdcondition = threading.Condition()
        self.cmdSingle = threading.Condition()
        self.process = process
        self.interpreter = GDBInterpreter()
        self.output = ''
        self.currentcmd = None
        self.log = Logger("GDBServer")
        self.completevisitor = CompleteVisitor()

    def run(self):
        lineCondition = threading.Condition()
        while(self.working):
            line = self.process.stdout.readline()
            if platform.system() == 'Windows':
                line = line.replace(os.sep + os.sep + '', os.sep)
                line = line.replace('/', os.sep)
            self.log.info(line)
            self.output += line
            if self.currentcmd != None and not self.currentcmd.isComplete():
                self.completevisitor.setoutput(self.output)
                self.currentcmd.accept(self.completevisitor)

            if self.currentcmd != None and self.currentcmd.isComplete():
                self.cmdcondition.acquire()
                self.cmdcondition.notify()
                self.cmdcondition.release()
    
    def send(self,cmd):
        self.cmdSingle.acquire()
        self.output = ''
        self.currentcmd = cmd
        self.log.info("Write -> " + str(cmd.getValue()))
        self.cmdcondition.acquire()
        self.process.stdin.write(cmd.getValue())
        self.cmdcondition.wait(15)

        try:
            if self.currentcmd.isComplete() == True:
                self.interpreter.parse(self.currentcmd,self.output.split('\n')) 
        finally:
            self.cmdcondition.release()
            self.cmdSingle.release()


    # FIXME: Start gdb without confirmation questions
    def stopserver(self):
        self.output = ''
        self.process.stdin.write("quit\n")
        self.working = False
Example #2
0
 def __init__(self):
     self.core = False
     self.log = Logger("Gdb")
     self.factory = CommandFactory()
     self.state = GDBState()
     self.fileLocationListeners = []
     self.binary = 'gdb'
Example #3
0
 def __init__(self,process):
     Thread.__init__(self)
     self.working = True
     self.cmdcondition = threading.Condition()
     self.cmdSingle = threading.Condition()
     self.process = process
     self.interpreter = GDBInterpreter()
     self.output = ''
     self.currentcmd = None
     self.log = Logger("GDBServer")
     self.completevisitor = CompleteVisitor()
Example #4
0
class GDB():
    def __init__(self):
        self.core = False
        self.log = Logger("Gdb")
        self.factory = CommandFactory()
        self.state = GDBState()
        self.fileLocationListeners = []
        self.binary = 'gdb'

    def __del__(self):
        if self.isConnected():
            self.disconnect()

    def gdbBinary(self, binary):
        self.binary = binary

    def connectApp(self, apppath):
        if self.isConnected() == True:
            raise AlreadyConnectedError()

        self.apppath = apppath
        handle = open(self.apppath);
        handle.close();
        arguments = [self.binary,'-n','-i','mi','-q',self.apppath]
        self.connect(arguments)
        self.changeDirectory(path.dirname(arguments[5])) 
    
    def connectCore(self,apppath,corepath):
        if self.isConnected() == True:
            raise AlreadyConnectedError()
        self.apppath = apppath
        arguments = [self.binary,'-n', '-i','mi','-q', self.apppath, corepath]
        self.connect(arguments)

    def connectRemote(self, host):
        if(self.isConnected() == True):
                raise AlreadyConnectedError()
        self.host = host
        arguments = [self.binary,'-n', '-i','mi','-q']
        self.connect(arguments)
        self.checkConnection()
        cmd = self.factory.createTargetCommand(host)
        self.gdbserver.send(cmd)
        if cmd.getTimeoutError() == True:
            raise TimeoutError('Connection timed out.')


    def connect(self,arguments):
        if self.isConnected() == True:
            raise AlreadyConnectedError()
        self.process = subprocess.Popen(arguments,
                shell=False,stdin=subprocess.PIPE,
                stdout = subprocess.PIPE)
        self.gdbserver = GDBServer(self.process)
        self.gdbserver.start()
        self.state.setConnected(True)

    def addNewFileLocationListener(self, listener):
        self.fileLocationListeners.append(listener)

    def newFileLocationListeners(self):
        return self.fileLocationListeners

    def removeNewFileLocationListener(self, listener):
        self.fileLocationListeners.remove(listener)

    def setTty(self, tty):
        self.checkConnection();
        cmd = self.factory.createTtyCommand(tty)
        self.gdbserver.send(cmd)

    def addExitListener(self, listener):
        self.exitListeners.append(listener)

    def changeDirectory(self,directory):
        self.checkConnection();
        cmd = self.factory.createChangeDirectoryCommand(directory)
        self.gdbserver.send(cmd)

    def setCore(self,value):
        self.checkConnection()
        self.core = value

    def getSourceCodeFiles(self):
        self.checkConnection()
        cmd = self.factory.createInfoSourceCommand()
        self.gdbserver.send(cmd)
        return cmd.getSourceFiles()

    def symbolFile(self, symbol):
        self.checkConnection()
        cmd = self.factory.createSymbolFileCommand(symbol)
        self.gdbserver.send(cmd)
        return cmd.getSymbolFile()

    def load(self, symbol):
        self.checkConnection()
        cmd = self.factory.createLoadCommand(symbol)
        self.gdbserver.send(cmd)

    def addBreakpoint(self, filename, line):
        self.checkConnection();
        cmd = self.factory.createAddBreakpointCommand(filename,line)
        self.gdbserver.send(cmd)    

    def getBreakpoints(self):
        self.checkConnection();
        cmd  = self.factory.createInfoBreakpointCommand()
        self.gdbserver.send(cmd)
        breakpoints = cmd.getBreakpoints()

        files = self.getSourceCodeFiles()

        for b in breakpoints:
            for f in files:
                if b.getSourceFile() == f['file']:
                    b.setSourceFile(f['fullname'])
        
        return breakpoints

    def deleteBreakpoint(self, number):    
        self.checkConnection()
        cmd = self.factory.createDeleteBreakpointCommand(number)
        self.gdbserver.send(cmd)

    def deleteAllBreakpoints(self):
        self.checkConnection()
        cmd = self.factory.createDeleteAllBreakpointsCommand()
        self.gdbserver.send(cmd)

    def addWatchpoint(self):
        self.checkConnection();
    
    def deleteWatchpoint(self):
        self.checkConnection();
    
    def infoThreads(self):
        self.checkConnection();
    
    def addDirectory(self,directory):
        self.checkConnection();
        cmd = self.factory.createAddDirectoryCommand(directory)
        self.gdbserver.send(cmd)

    def checkConnection(self):
        if not self.isConnected():
            raise NotConnectedError("GDB must be connected before using this method");

    def run(self, arguments):
        self.checkConnection()
        cmd = self.factory.createRunCommand(arguments)
        self.gdbserver.send(cmd)
        location = cmd.getLocation()
        if location.has_key('fullname'):
            self.log.debug("Reporting new location: " + location['fullname'] +":"+str(location['line']))
            self.updateNewFileLocationListeners(location['fullname'], location['line'])
    
    def step(self):
        self.checkConnection();
        cmd = self.factory.createStepCommand()
        self.gdbserver.send(cmd)
        location = cmd.getLocation()
        if location.has_key('fullname'):
            self.log.debug("Reporting new location: " + location['fullname'] +":"+str(location['line']))
            self.updateNewFileLocationListeners(location['fullname'], location['line'])
    
    def next(self):
        self.checkConnection();
        cmd = self.factory.createNextCommand()
        self.gdbserver.send(cmd)
        location = cmd.getLocation()
        if location.has_key('fullname'):
            self.log.debug("Reporting new location: " + location['fullname'] +":"+str(location['line']))
            self.updateNewFileLocationListeners(location['fullname'], location['line'])

    def p(self, expression):
        self.checkConnection()
        cmd = self.factory.createPrintCommand(expression)
        self.gdbserver.send(cmd)
        value = cmd.getResult()
        return value

    def backtrace(self):
        self.checkConnection();
        cmd = self.factory.createBacktraceCommand()
        self.gdbserver.send(cmd)
        self.observer.printBacktrace(cmd.getBacktrace())

    def updateNewFileLocationListeners(self, newFile, newLine):
        for listener in self.fileLocationListeners:
            listener.newFileLocation(newFile, newLine)

    def finish(self):
        self.checkConnection();

    def until(self):
        self.checkConnection();

    def clear(self, filename, lineNumber):
        self.checkConnection();
        cmd = self.factory.createClearCommand(filename, lineNumber)
        self.gdbserver.send(cmd)

       
    def continueExecution(self):
        self.checkConnection();
        cmd = self.factory.createContinueCommand()
        self.gdbserver.send(cmd)


    def whatIs(self,variable):
        self.checkConnection();

    def setVar(self, variable, value):
        self.checkConnection();

    def jump(self):
        self.checkConnection();
    
    def call(self):
        self.checkConnection();

    def returnExecution(self):
        self.checkConnection();

    def getState(self):
        return self.state

    def disconnect(self):
        self.checkConnection();
        self.gdbserver.stopserver()
        self.state.setConnected(False)
        #self.monitor.destroy()

    def isConnected(self):
        return self.state.isConnected()