- Changed backtrace view to a treeview
authorStefan Huber <shuber2@gmail.com>
Fri, 4 Jul 2008 08:54:38 +0000 (10:54 +0200)
committerStefan Huber <shuber2@gmail.com>
Fri, 4 Jul 2008 08:54:38 +0000 (10:54 +0200)
- By double-clicking on a bt-entry vim jumps to position

DbgTerminal.py
GdbTerminal.py
INSTALL.txt
PositionFrame.py
StatusWindow.py
featurerequest.txt

index a899a6358bdbdc3a4f4c6896bb6d16d69f8c6dba..9d08866820acc3083048b589c78f4b54eacc30f2 100644 (file)
@@ -100,6 +100,8 @@ class DbgTerminal (vte.Terminal):
                                        for cb in self.gotInactiveCallback:
                                                cb(status, param)
                except Exception, e:
+                       import traceback
+                       traceback.print_exc()
                        print e
 
                return True
index f8a8614e1f3c7dd1040f616d52987233894fe74d..842f76862123027b809e690aebab5fda54ae220b 100644 (file)
@@ -154,7 +154,53 @@ class GdbTerminal (DbgTerminal.DbgTerminal):
                return self.__getAnswerFromCmd("list\n")
 
        def getBacktrace(self):
-               return self.__getAnswerFromCmd("bt\n")
+
+               stack = []
+               answ = self.__getAnswerFromCmd("bt\n")
+
+               rxstartfull = re.compile("^\#\d+\s+0x[0-9a-f]+\s+in\s+\S+\s+\(")
+               rxstartshort = re.compile("^\#\d+\s+\S+\s+\(")
+               rxpos = re.compile("at \S+:\d+$")
+
+               try:
+
+                       i=0
+                       while i<len(answ):
+                               line = answ[i]
+
+                               while not rxstartfull.search(line) and not rxstartshort.search(line):
+                                       print "Warning: '", line, "' does not match bt entry."
+                                       i+=1
+                                       line = answ[i]
+
+                               parts = line.split()
+
+                               if rxstartfull.search(line):
+                                       func = parts[3]
+                                       addr = parts[1]
+                               else:
+                                       func = parts[1]
+                                       addr = None
+
+
+                               #Search for file position
+                               while not rxpos.search(line):
+                                       print "Warning: '", line, "' does not match file pos marker."
+                                       i+=1
+                                       line = answ[i]
+
+                               parts = line.split()
+                               pos = parts[-1]
+                               [file,lineno] = pos.split(":")
+
+                               stack += [[addr,func,file,lineno]]
+
+                               i+=1
+
+               except IndexError:
+                       pass
+
+               return stack
 
        def waitForPrompt(self, his):
                rx = "^\(gdb\)"
index cbcf4ecf78de76ee54d7db015973d20f4cc747d0..759bbaa058384eeef15a88955d7928cdda1d39c8 100644 (file)
@@ -18,7 +18,4 @@
    add <dir> to the environment variable PATH such that you can call pygdb
    from console directly.
 
-   If you like, you can add the following line. It leads to a configuration file
-   loading when opening a source file
-       autocmd BufRead *.c*  :GDBLoadConfig
-
+  
index 0eb49f34bd3e15c71c49ae774cf7db6a4cad4a24..035f32d097bf28a51860e2402f812e4d4467168a 100644 (file)
@@ -18,15 +18,17 @@ import StatusFrame
 class PositionFrame (StatusFrame.StatusFrame):
 
 
-       def __init__(self, debugger):
+       def __init__(self, debugger, statuswnd):
 
                StatusFrame.StatusFrame.__init__(self, debugger)
                self.set_label("Position")
 
+               self.statuswnd = statuswnd
                debugger.gotActiveCallback += [self.updateValues]
                debugger.gotInactiveCallback += [self.updateValues]
 
                self.file = None
+               self.bt = None
                self.lineno = 0
 
                vbox = gtk.VBox(False, 5)
@@ -44,12 +46,54 @@ class PositionFrame (StatusFrame.StatusFrame):
                sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
                vbox.add(sw)
 
-               self.srcview = gtk.TextView()
-               sw.add(self.srcview)
+               self.model = self.__createModel()
+               self.tv = gtk.TreeView(self.model)
+               self.tv.set_rules_hint(True)
+               self.tv.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+               self.tv.connect("row-activated", self.rowactivated)
+
+               self.__addColumns(self.tv)
+               sw.add(self.tv)
 
                self.openBtn.connect("clicked", self.openBtnClicked)
 
 
+       def __createModel(self):        
+               model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, \
+                               gobject.TYPE_STRING, gobject.TYPE_STRING)
+
+               return model
+
+
+       def __addColumns(self, tv):
+
+               model = tv.get_model()
+
+               renderer = gtk.CellRendererText()
+               renderer.set_data("column", 0)
+               col = gtk.TreeViewColumn("Addr", renderer, text=0)
+               col.set_resizable(True)
+               tv.append_column(col)
+
+               renderer = gtk.CellRendererText()
+               renderer.set_data("column", 1)
+               col = gtk.TreeViewColumn("Func", renderer, text=1)
+               col.set_resizable(True)
+               tv.append_column(col)
+
+               renderer = gtk.CellRendererText()
+               renderer.set_data("column", 2)
+               col = gtk.TreeViewColumn("File", renderer, text=2)
+               col.set_resizable(True)
+               tv.append_column(col)
+
+               renderer = gtk.CellRendererText()
+               renderer.set_data("column", 3)
+               col = gtk.TreeViewColumn("Lin", renderer, text=3)
+               col.set_resizable(True)
+               tv.append_column(col)
+
+
        def openBtnClicked(self, btn):
 
                if not self.debugger.isActive():
@@ -68,22 +112,49 @@ class PositionFrame (StatusFrame.StatusFrame):
                                dialog.destroy()
 
 
+       def rowactivated(self, tv, path, col, *w):
+               no, = path
+               no = int(no)
+               entry = self.bt[no]
+               self.statuswnd.gotoVim(entry[2], entry[3])
+
+       
+
        def updateValues(self, status, param):
                
-               #Create new text buffer for source view
-               buf = gtk.TextBuffer()
 
-               if status == "break":           
+               #Remove them all
+               iter = self.model.get_iter_first()
+               while iter != None:
+                       newiter = self.model.iter_next(iter)
+                       self.model.remove(iter)
+                       iter = newiter
+
+
+               if status == "break":
+
+       
+                       #Set current file position
                        self.file, self.lineno = param
                        self.positionLabel.set_label("%s:%d" % (self.file, self.lineno))
 
-                       #Get some code
-                       code = string.join(self.debugger.getBacktrace(), "\n")
-                       buf.set_text(code)
+                       #Add the entries
+                       self.bt = self.debugger.getBacktrace()
+                       for [addr, func, file, lineno] in self.bt:
+                               iter = self.model.append()
+
+                               if addr!=None:
+                                       self.model.set(iter, 0, addr)   
+
+                               self.model.set(iter, 1, func)
+                               self.model.set(iter, 2, file)
+                               self.model.set(iter, 3, lineno)
+
 
 
                else:
                        self.file, self.lineno = None, None
+                       self.bt = None
                        code = ""
 
                        if status == "exited":
@@ -96,10 +167,6 @@ class PositionFrame (StatusFrame.StatusFrame):
                                self.positionLabel.set_label(status)
 
        
-               #Set the buffer
-               self.srcview.set_buffer(buf)
-
-
                
 
        def applyConfiguration(self, conf):
index f03c11c27d579173db6641aa42d5394b842d9e52..ae9903637ed48b4edd96a66bd2db775e5224c346 100644 (file)
@@ -40,7 +40,7 @@ class StatusWindow (gtk.Window):
        
                #Adding the frames
                self.frames = []
-               self.frames += [PositionFrame.PositionFrame(debugger), \
+               self.frames += [PositionFrame.PositionFrame(debugger,self), \
                                WatchesFrame.WatchesFrame(debugger), \
                                BreakpointsFrame.BreakpointsFrame(debugger) ]
 
@@ -106,8 +106,12 @@ class StatusWindow (gtk.Window):
 
 
        def updateVim(self):
-
                os.system('gvim --servername %s --remote-send "<ESC> :GDBLoadConfig<CR>"' % \
                        self.vimservername)
 
+       def gotoVim(self, file, lineno):
+               file = self.debugger.toAbsPath(file)            
+               os.system('gvim --servername %s --remote-send "<ESC>:e %s<CR>:%s<CR>"' % \
+                       (self.vimservername, file, lineno))
+
 
index 68f92bf313a5de9ec6462e8546887ae96bf21baa..0922e513bd2836caa8b54db84dfdd97c810155f4 100644 (file)
@@ -1,7 +1,8 @@
 Smaller requests
 
 Medium requestes:
-  - double-click on backtrace entries
+  - local variables frame
+  - double-click on backtrace entries --> open source file
   - keyboard shortcuts for run/continue/etc
   - Deactivate breakpoints