From: Stefan Huber Date: Mon, 2 Jun 2008 12:22:23 +0000 (+0200) Subject: added functions for getting dbg replies X-Git-Tag: v0.99.0~44 X-Git-Url: https://git.sthu.org/?p=pygdb.git;a=commitdiff_plain;h=65010f5074ddf1f3ccb7424aaec7ab78c2ede09d added functions for getting dbg replies --- diff --git a/DbgTerminal.py b/DbgTerminal.py index cef0d27..88064db 100755 --- a/DbgTerminal.py +++ b/DbgTerminal.py @@ -2,16 +2,22 @@ import select +import string import sys import thread import threading import time import os import pty +import Queue class DbgTerminal: + #Reply cache from debugger + dbgreplyqueue = Queue.Queue() + + def __init__ (self, binary, gdbReadCallback, childReadCallback): #Set some members @@ -25,43 +31,41 @@ class DbgTerminal: def __connect( self ): + #This function handles readings from the debugger + def gdbCb(str): + self.gdbReadCallback(str) + self.dbgreplyqueue.put(str) #Open pseudo-terminal where to-be-debugged process reads/writes to self.ptymaster, self.ptyslave = pty.openpty() self.childout = os.fdopen(self.ptymaster, "r", 0) self.childin = os.fdopen(self.ptymaster, "w", 0) - #Open the subprocess and get in- and out-streams + #Call gdb and get in- and out-streams to/from gdb cmd = self.getCommand(self.binary) self.gdbin, self.gdbout = os.popen4( cmd, bufsize=0) - #Set up a reading thread to gdb output - self.gdbReadThread = self.ReadThread(self.gdbout, self.gdbReadCallback) + self.gdbReadThread = self.ReadThread(self.gdbout, gdbCb) self.gdbReadThread.start() - #Set up a reading thread to gdb output + #Set up a reading thread to childs output self.childReadThread = self.ReadThread(self.childout, self.childReadCallback) self.childReadThread.start() #Set up tty gdb-childs process - time.sleep(0.1) self.sendSetTTY(os.ttyname(self.ptyslave)) - time.sleep(0.1) - + - def getCommand( self, binary ): - """Get the command to execute""" + def getDbgReply(self): raise NotImplementedError() def iseof( self ): """Check if terminal is closed already""" - return self.gdbReadThread.eventFin.isSet() - def stop( self ): if not self.stopped: @@ -75,6 +79,10 @@ class DbgTerminal: self.childReadThread.eventFin.wait(1) + def getCommand( self, binary ): + """Get the command to execute""" + raise NotImplementedError() + def sendBreak(self, file, lineno): raise NotImplementedError() @@ -136,6 +144,9 @@ class DbgTerminal: class GdbTerminal (DbgTerminal): + gdbreply = "" + + def getCommand( self, binary ): return "gdb --fullname %s" % (binary,) @@ -161,7 +172,32 @@ class GdbTerminal (DbgTerminal): self.gdbin.write("quit\n") DbgTerminal.stop(self) + def getDbgReply(self, timeout=None): + while True: + splits = self.gdbreply.split("\n") + + #Need more data: If there is a single (gdb) entry, then + #there are at least two splits + if len(splits) <= 1: + try: + self.gdbreply += self.dbgreplyqueue.get(True, timeout) + except Queue.Empty: + return None + #Yeah there is data! + else: + self.gdbreply = string.join(splits[1:], "(gdb)") + return string.strip(splits[0]) + + def flushDbgReply(self): + + try: + self.gdbreply = "" + #Remove all elements from queue + while True: + self.dbgreplyqueue.get(False) + except Queue.Empty: + pass if __name__ == "__main__": @@ -173,13 +209,34 @@ if __name__ == "__main__": term = GdbTerminal( "./main", tostdout, tostdout) term.sendBreak("main.cpp", 13) + term.sendBreak("main.cpp", 14) term.sendRun() term.childin.write("1\n"); term.childin.write("2\n"); + + time.sleep(0.2) + term.flushDbgReply() + term.sendInspectVar("a+b") + + term.sendContinue() term.sendInspectVar("a+b") term.sendContinue() + time.sleep(1) + + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + print "reply >>>", term.getDbgReply(1) + + while not term.iseof(): cmd = sys.stdin.readline()