From f2698c930f26434a100e0b4c1e4f39291b55b4f9 Mon Sep 17 00:00:00 2001 From: Stefan Huber Date: Mon, 9 Jun 2008 20:07:27 +0200 Subject: [PATCH] - Fixed bug when bp is set on same addr - Adding Configuration loading/writing - Introducing common StatusFrame class --- BreakpointsFrame.py | 23 +++++++--- Configuration.py | 99 ++++++++++++++++++++++++++++++++++++++++++++ DbgTerminal.py | 20 ++++----- GdbTerminal.py | 21 +++++----- MainControlWindow.py | 10 ++--- StatusFrame.py | 26 ++++++++++++ StatusWindow.py | 50 +++++++++++++--------- WatchesFrame.py | 27 ++++++++---- pygdb.py | 39 +++++++---------- pygdb.vim | 8 +++- 10 files changed, 238 insertions(+), 85 deletions(-) create mode 100755 Configuration.py create mode 100644 StatusFrame.py diff --git a/BreakpointsFrame.py b/BreakpointsFrame.py index 9b709b4..3093fbb 100644 --- a/BreakpointsFrame.py +++ b/BreakpointsFrame.py @@ -11,15 +11,16 @@ import string import vte import DbgTerminal +import StatusFrame -class BreakpointsFrame (gtk.Frame): +class BreakpointsFrame (StatusFrame.StatusFrame): def __init__(self, debugger): - gtk.Frame.__init__(self, "Breakpoints") - self.debugger = debugger + StatusFrame.StatusFrame.__init__(self, debugger) + self.set_label("Breakpoints") vbox = gtk.VBox(False, 5) self.add(vbox) @@ -135,6 +136,18 @@ class BreakpointsFrame (gtk.Frame): dialog.destroy() + def applyConfiguration(self, conf): + for b in conf.breakpoints: + self.addBreakpoint(b["file"], b["lineno"], b["cond"]) + + def fillConfiguration(self, conf): + iter = self.model.get_iter_first() + while iter != None: + spec, = self.model.get(iter, 1) + conf.parseBreak(spec) + iter = self.model.iter_next(iter) + + def addBreakpointToList(self, no, file, lineno, cond=None): iter = self.model.append() @@ -167,10 +180,10 @@ class BreakpointsFrame (gtk.Frame): if not self.debugger.isActive(): return - self.updateValues() + self.updateValues(None) - def updateValues(self): + def updateValues(self, pos): bpnts = self.debugger.getBreakpoints() diff --git a/Configuration.py b/Configuration.py new file mode 100755 index 0000000..7dcd290 --- /dev/null +++ b/Configuration.py @@ -0,0 +1,99 @@ +#!/usr/bin/python +#shuber, 2008-06-09 + +__author__ = "shuber" + + + +import re +import string + +import StatusWindow + +class Configuration: + + def __init__(self): + self.breakpoints = [] + self.watches = [] + + + def load(self, filename): + try: + cnt = 0 + #Parse all lines + for line in file(filename).readlines(): + cnt += 1 + + #Get command and tail + cmd = string.split(line)[0] + tail = string.join(string.split(line)[1:]) + + if cmd == "break": + self.parseBreak(tail) + elif cmd == "watch": + self.parseWatch(tail) + else: + cnt -= 1 + print "Unkown command", cmd + return cnt + except IOError: + return None + + def store(self, filename): + + f = file(filename, "w") + + for b in self.breakpoints: + self.__writeBreak(f, b) + + for w in self.watches: + self.__writeWatch(f, w) + + + def parseBreak(self, tail): + + tail = tail.strip() + rx = re.compile("^[\w\._\-]+:\d+(\s+if\s+\S+.*)?$") + + if not rx.search(tail): + print "Wrong breakpoint format:", tail + return + + preif = string.split(tail, "if")[0].strip() + postif = string.join( string.split(tail, "if")[1:], "if").strip() + + [file,lineno] = string.split(preif, ":") + lineno = int(lineno) + + cond = None + if postif != "": + cond = postif + + self.addBreak(file, lineno, cond) + + + def parseWatch(self, tail): + self.addWatch(tail) + + + def __writeBreak(self, f, b): + if b["cond"] != None: + f.write("break %(file)s:%(lineno)d if %(cond)s\n" % b) + else: + f.write("break %(file)s:%(lineno)d\n" % b) + + def __writeWatch(self, f, w): + f.write("watch %(expr)s\n" % w) + + + def addBreak(self, file, lineno, cond=None): + self.breakpoints += [ {"file" : file, "lineno" : lineno, "cond" : cond} ] + + def addWatch(self, expr): + self.watches += [ {"expr" : expr.strip() } ] + + def __str__(self): + return "breakpoints=" + str(self.breakpoints) + ", watches=" + str(self.watches) + + + diff --git a/DbgTerminal.py b/DbgTerminal.py index 21aa1c4..8beec46 100644 --- a/DbgTerminal.py +++ b/DbgTerminal.py @@ -19,20 +19,15 @@ import ClientIOTerminal class DbgTerminal (vte.Terminal): - isactive = True - lastrow = 0 - history = [] - childpid = None - - - def __init__(self, clientCmd, exitcb=None): + def __init__(self, clientCmd): vte.Terminal.__init__(self) - def onChildExited(): - self.childpid = None - if exitcb != None: - exitcb() + #Set members + self.childpid = None + self.history = [] + self.lastrow = 0 + self.isactive = True #Start debugger self.clientCmd = clientCmd @@ -41,7 +36,7 @@ class DbgTerminal (vte.Terminal): #Set up terminal window and initialize debugger self.connect("cursor-moved", self.contents_changed) - self.connect("child-exited", lambda *w: onChildExited()) + self.connect("child-exited", lambda *w: gtk.main_quit()) #font description fontdesc = pango.FontDescription("monospace 9") @@ -56,6 +51,7 @@ class DbgTerminal (vte.Terminal): def stopDbg(self): if self.childpid != None: + #9=KILL, 15=TERM os.kill(self.childpid, 15); self.childpid = None diff --git a/GdbTerminal.py b/GdbTerminal.py index 4fb4a35..304e39a 100755 --- a/GdbTerminal.py +++ b/GdbTerminal.py @@ -17,8 +17,8 @@ import DbgTerminal class GdbTerminal (DbgTerminal.DbgTerminal): - def __init__(self, clientCmd, exitcb=None): - DbgTerminal.DbgTerminal.__init__(self, clientCmd, exitcb) + def __init__(self, clientCmd): + DbgTerminal.DbgTerminal.__init__(self, clientCmd) def getArgv(self): return ["gdb", "--fullname", string.split(self.clientCmd)[0]] @@ -34,7 +34,6 @@ class GdbTerminal (DbgTerminal.DbgTerminal): self.feed_child("run " + argv + "\n") return self.waitForActivation(his) - def setContinue(self): his = self.getHistoryLen() self.feed_child("cont\n"); @@ -63,20 +62,22 @@ class GdbTerminal (DbgTerminal.DbgTerminal): self.feed_child("break %s:%s if %s\n" % \ (file, str(lineno), condition)) - rx = re.compile("^Breakpoint |^No|^\(gdb\) ") + rx = re.compile("^Breakpoint |^No |^\(gdb\) ") his, response = self.waitForRx(rx, his) if response[0:10] == "Breakpoint": return string.split(response)[1].strip() - if response[0:5] == "(gdb)": - return None + if response[0:14] == "No source file": self.feed_child("n\n"); return None - if response[0:3] == "No ": - return None - - return NotImplementedError() + + #Wait again for gdb + if response[0:5] != "(gdb)": + his, response = self.waitForRx(rx,his) + + return None + def delBreakpoint(self, breakpoint): self.feed_child("del breakpoint %s\n" % (breakpoint,)) diff --git a/MainControlWindow.py b/MainControlWindow.py index 6dbbf2e..13d32ee 100644 --- a/MainControlWindow.py +++ b/MainControlWindow.py @@ -16,16 +16,14 @@ import ClientIOTerminal class MainControlWindow (gtk.Window): - #Callbacks for new positions - newPosCbs = [] - - def __init__(self, dbgterm, closecb=None): + def __init__(self, dbgterm): #Set up GTK stuff gtk.Window.__init__(self) + self.connect("destroy", lambda *w: gtk.main_quit() ) - if closecb!=None: - self.connect("destroy", lambda *w: closecb() ) + #Callbacks for new positions + self.newPosCbs = [] #Set terminals self.dbgterm = dbgterm diff --git a/StatusFrame.py b/StatusFrame.py new file mode 100644 index 0000000..37f7bbf --- /dev/null +++ b/StatusFrame.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +#shuber, 2008-06-09 + +__author__ = "shuber" + + +import gtk + + +class StatusFrame (gtk.Frame): + + def __init__(self, debugger): + gtk.Frame.__init__(self) + self.debugger = debugger + + def applyConfiguration(self, conf): + raise NotImplemented() + + def fillConfiguration(self, conf): + raise NotImplemented() + + def updateValues(self, pos): + raise NotImplemented() + + + diff --git a/StatusWindow.py b/StatusWindow.py index 84811c2..121c0b8 100644 --- a/StatusWindow.py +++ b/StatusWindow.py @@ -7,29 +7,22 @@ __author__ = "shuber" import gtk import vte -import WatchesFrame import BreakpointsFrame +import WatchesFrame + class StatusWindow (gtk.Window): - def __init__(self, mainctrlwnd, debugger, closecb=None): + def __init__(self, mainctrlwnd, debugger): gtk.Window.__init__(self) - self.set_screen(mainctrlwnd.get_screen()) - + self.debugger = debugger + self.set_border_width(5) self.set_title("Status") self.set_default_size(400,600) - - if closecb!=None: - self.connect("destroy", lambda *w: closecb()) - - - #Register callback function for new positions - self.mainctrlwnd = mainctrlwnd - mainctrlwnd.newPosCbs += [self.updateValues] - + self.connect("destroy", lambda *w: gtk.main_quit()) vbox = gtk.VBox(False, 5) self.add(vbox) @@ -39,15 +32,34 @@ class StatusWindow (gtk.Window): vpaned = gtk.VPaned() vbox.add(vpaned) - self.watchesFrame = WatchesFrame.WatchesFrame(debugger) - vpaned.add1(self.watchesFrame) + #Adding the frames + self.frames = [] + self.frames += [WatchesFrame.WatchesFrame(debugger)] + self.frames += [BreakpointsFrame.BreakpointsFrame(debugger)] + vpaned.add1(self.frames[0]) + vpaned.add2(self.frames[1]) - self.breakpointsFrame = BreakpointsFrame.BreakpointsFrame(debugger) - vpaned.add2(self.breakpointsFrame) + #Register callback function for new positions + #and update the values + mainctrlwnd.newPosCbs += [self.updateValues] self.show_all() + def applyConfiguration(self, conf): + + while not self.debugger.isActive(): + gtk.main_iteration() + + for f in self.frames: + f.applyConfiguration(conf) + + + def fillConfiguration(self, conf): + for f in self.frames: + f.fillConfiguration(conf) + + def updateValues(self, pos): if pos == None: @@ -56,7 +68,7 @@ class StatusWindow (gtk.Window): file, lineno = pos self.status.set_text("%s:%s" % (file, lineno)) - self.watchesFrame.updateValues() - self.breakpointsFrame.updateValues() + for f in self.frames: + f.updateValues(pos) diff --git a/WatchesFrame.py b/WatchesFrame.py index a792501..675e47c 100644 --- a/WatchesFrame.py +++ b/WatchesFrame.py @@ -9,15 +9,16 @@ import gtk import vte import DbgTerminal +import StatusFrame -class WatchesFrame (gtk.Frame): +class WatchesFrame (StatusFrame.StatusFrame): def __init__(self, debugger): - gtk.Frame.__init__(self, "Watches") - self.debugger = debugger + StatusFrame.StatusFrame.__init__(self, debugger) + self.set_label("Watches") vbox = gtk.VBox(False, 5) self.add(vbox) @@ -87,13 +88,25 @@ class WatchesFrame (gtk.Frame): model.set(iter, 1, res) + def applyConfiguration(self, conf): + for w in conf.watches: + iter = self.model.append() + self.model.set(iter, 0, w["expr"], 1, "", 2, True) + self.updateValues(None) + + + def fillConfiguration(self, conf): + iter = self.model.get_iter_first() + while iter != None: + expr, = self.model.get(iter, 0) + conf.parseWatch(expr) + iter = self.model.iter_next(iter) def addBtnClicked(self, btn): iter = self.model.append() self.model.set(iter, 0, "0", 1, "0", 2, True) - def delBtnClicked(self, btn): selection = self.tv.get_selection() model, paths = selection.get_selected_rows() @@ -102,13 +115,9 @@ class WatchesFrame (gtk.Frame): iter = model.get_iter(path) model.remove(iter) - - def updateValues(self): - + def updateValues(self, pos): iter = self.model.get_iter_first() - while iter != None: - expr, = self.model.get(iter, 0) res = self.debugger.getExpression(expr) self.model.set(iter, 1, res) diff --git a/pygdb.py b/pygdb.py index d3cf269..6b6f5d3 100755 --- a/pygdb.py +++ b/pygdb.py @@ -8,39 +8,33 @@ import os import string import sys +import Configuration import GdbTerminal import MainControlWindow import StatusWindow -def launchDebugger(clientCmd, quitonclose=True): - - - - def hideWindows(): - #Kill the debugger - dbgterm.stopDbg() - - mainCtrlWnd.destroy() - statusWnd.destroy() - gtk.main_quit() - - - #Determine the closing callback func - if quitonclose: - destroycb = gtk.main_quit - else: - destroycb = hideWindows +def launchDebugger(clientCmd): #Create Terminal - dbgterm = GdbTerminal.GdbTerminal(clientCmd, destroycb) + dbgterm = GdbTerminal.GdbTerminal(clientCmd) #Create windows - mainCtrlWnd = MainControlWindow.MainControlWindow(dbgterm, destroycb) - statusWnd = StatusWindow.StatusWindow(mainCtrlWnd, dbgterm, destroycb) + mainCtrlWnd = MainControlWindow.MainControlWindow(dbgterm) + statusWnd = StatusWindow.StatusWindow(mainCtrlWnd, dbgterm) dbgterm.initialize() - return dbgterm, mainCtrlWnd, statusWnd + #Load configuration + conf = Configuration.Configuration() + conf.load(".pygdb.conf") + statusWnd.applyConfiguration(conf) + + gtk.main() + + #Store config + conf = Configuration.Configuration() + statusWnd.fillConfiguration(conf) + conf.store(".pygdb.conf") @@ -54,6 +48,5 @@ if __name__ == "__main__": #Create the terminals clientCmd = string.join(sys.argv[1:]) launchDebugger(clientCmd) - gtk.main() diff --git a/pygdb.vim b/pygdb.vim index 244e632..b67dd79 100644 --- a/pygdb.vim +++ b/pygdb.vim @@ -40,7 +40,13 @@ def gdbLaunch(): global gdbterm, mainctrlwnd, statuswnd, gdbBps, clientcmd, gdbthread - clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd) + clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd).strip() + + + if clientcmd.strip()=="": + print "No command given!" + return + gdbterm, mainctrlwnd, statuswnd = pygdb.launchDebugger(clientcmd, False) for bp in gdbBps: -- 2.30.2