public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-tromey-python: 'upto' commands
@ 2009-07-07 16:19 tromey
  0 siblings, 0 replies; only message in thread
From: tromey @ 2009-07-07 16:19 UTC (permalink / raw)
  To: archer-commits

The branch, archer-tromey-python has been updated
       via  4a725034fb654b938fd53dfdbc6069710d9335a3 (commit)
      from  3b08cd357baf7fe3e981fd30c69b30ca5afce865 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 4a725034fb654b938fd53dfdbc6069710d9335a3
Author: Tom Tromey <tromey@redhat.com>
Date:   Tue Jul 7 10:18:40 2009 -0600

    'upto' commands
    
    gdb
    	* python/python-symtab.c (stpy_get_objfile): New function.
    	(symtab_object_getset): Add "objfile".
    	* python/python-frame.c (frapy_select): New function.
    	(frame_object_methods): Add "select".
    	* python/lib/gdb/command/upto.py: New file.
    	* python/lib/gdb/command/backtrace.py: Move code to
    	FrameWrapper.py.
    	* python/lib/gdb/FrameWrapper.py: New file.
    	* Makefile.in (PY_FILES): Add new files.
    gdb/doc
    	* gdb.texinfo (Frames In Python): Document Frame.select.

-----------------------------------------------------------------------

Summary of changes:
 gdb/Makefile.in                         |    4 +-
 gdb/doc/gdb.texinfo                     |    4 +
 gdb/python/lib/gdb/FrameWrapper.py      |  112 +++++++++++++++++++++++++++
 gdb/python/lib/gdb/command/backtrace.py |   94 +----------------------
 gdb/python/lib/gdb/command/upto.py      |  129 +++++++++++++++++++++++++++++++
 gdb/python/python-frame.c               |   21 +++++
 gdb/python/python-symtab.c              |   13 +++-
 7 files changed, 281 insertions(+), 96 deletions(-)
 create mode 100644 gdb/python/lib/gdb/FrameWrapper.py
 create mode 100644 gdb/python/lib/gdb/command/upto.py

First 500 lines of diff:
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 0d8c3ed..947bcd5 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1957,9 +1957,9 @@ python-value.o: $(srcdir)/python/python-value.c
 
 # All python library files, with the "python/lib" stripped off.
 # Note that we should only install files in the "gdb" module.
-PY_FILES = gdb/FrameIterator.py gdb/command/alias.py \
+PY_FILES = gdb/FrameIterator.py gdb/FrameWrapper.py gdb/command/alias.py \
     gdb/command/backtrace.py gdb/command/require.py \
-    gdb/command/pahole.py gdb/command/__init__.py \
+    gdb/command/pahole.py gdb/command/upto.py gdb/command/__init__.py \
     gdb/command/ignore_errors.py gdb/command/save_breakpoints.py \
     gdb/function/caller_is.py gdb/function/in_scope.py \
     gdb/function/__init__.py gdb/backtrace.py gdb/__init__.py
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 234397e..7ac503f 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -20262,6 +20262,10 @@ Return the frame's symtab and line object. @c (@pxref{Symtab_and_line,, Symtab a
 Return the value of the given variable in this frame.  @var{variable} must
 be a string.
 @end defmethod
+
+@defmethod Frame select
+Set this frame to be the user's selected frame.
+@end defmethod
 @end table
 
 @node Interpreters
diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py
new file mode 100644
index 0000000..39f8246
--- /dev/null
+++ b/gdb/python/lib/gdb/FrameWrapper.py
@@ -0,0 +1,112 @@
+# Wrapper API for frames.
+
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gdb
+
+# FIXME: arguably all this should be on Frame somehow.
+class FrameWrapper:
+    def __init__ (self, frame):
+        self.frame = frame;
+
+    def write_symbol (self, stream, sym, block):
+        if len (sym.linkage_name):
+            nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block)
+            if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER:
+                sym = nsym
+
+        stream.write (sym.print_name + "=")
+        try:
+            val = self.frame.read_var (sym)
+            if val != None:
+                val = str (val)
+        # FIXME: would be nice to have a more precise exception here.
+        except RuntimeError, text:
+            val = text
+        if val == None:
+            stream.write ("???")
+        else:
+            stream.write (str (val))
+
+    def print_frame_locals (self, stream, func):
+        if not func:
+            return
+
+        first = True
+        block = func.value
+
+        for sym in block:
+            if sym.is_argument:
+                continue;
+
+            self.write_symbol (stream, sym, block)
+            stream.write ('\n')
+
+    def print_frame_args (self, stream, func):
+        if not func:
+            return
+
+        first = True
+        block = func.value
+
+        for sym in block:
+            if not sym.is_argument:
+                continue;
+
+            if not first:
+                stream.write (", ")
+
+            self.write_symbol (stream, sym, block)
+            first = False
+
+    # FIXME: this should probably just be a method on gdb.Frame.
+    # But then we need stream wrappers.
+    def describe (self, stream, full):
+        if self.frame.type () == gdb.DUMMY_FRAME:
+            stream.write (" <function called from gdb>\n")
+        elif self.frame.type () == gdb.SIGTRAMP_FRAME:
+            stream.write (" <signal handler called>\n")
+        else:
+            sal = self.frame.find_sal ()
+            pc = self.frame.pc ()
+            name = self.frame.name ()
+            if not name:
+                name = "??"
+            if pc != sal.pc or not sal.symtab:
+                stream.write (" 0x%08x in" % pc)
+            stream.write (" " + name + " (")
+
+            func = self.frame.function ()
+            self.print_frame_args (stream, func)
+
+            stream.write (")")
+
+            if sal.symtab and sal.symtab.filename:
+                stream.write (" at " + sal.symtab.filename)
+                stream.write (":" + str (sal.line))
+
+            if not self.frame.name () or (not sal.symtab or not sal.symtab.filename):
+                lib = gdb.solib_address (pc)
+                if lib:
+                    stream.write (" from " + lib)
+
+            stream.write ("\n")
+
+            if full:
+                self.print_frame_locals (stream, func)
+
+    def __getattr__ (self, name):
+        return getattr (self.frame, name)
diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py
index c49fd55..ec9a527 100644
--- a/gdb/python/lib/gdb/command/backtrace.py
+++ b/gdb/python/lib/gdb/command/backtrace.py
@@ -19,101 +19,9 @@ import gdb
 import gdb.backtrace
 import itertools
 from gdb.FrameIterator import FrameIterator
+from gdb.FrameWrapper import FrameWrapper
 import sys
 
-class FrameWrapper:
-    def __init__ (self, frame):
-        self.frame = frame;
-
-    def write_symbol (self, stream, sym, block):
-        if len (sym.linkage_name):
-            nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block)
-            if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER:
-                sym = nsym
-
-        stream.write (sym.print_name + "=")
-        try:
-            val = self.frame.read_var (sym)
-            if val != None:
-                val = str (val)
-        # FIXME: would be nice to have a more precise exception here.
-        except RuntimeError, text:
-            val = text
-        if val == None:
-            stream.write ("???")
-        else:
-            stream.write (str (val))
-
-    def print_frame_locals (self, stream, func):
-        if not func:
-            return
-
-        first = True
-        block = func.value
-
-        for sym in block:
-            if sym.is_argument:
-                continue;
-
-            self.write_symbol (stream, sym, block)
-            stream.write ('\n')
-
-    def print_frame_args (self, stream, func):
-        if not func:
-            return
-
-        first = True
-        block = func.value
-
-        for sym in block:
-            if not sym.is_argument:
-                continue;
-
-            if not first:
-                stream.write (", ")
-
-            self.write_symbol (stream, sym, block)
-            first = False
-
-    # FIXME: this should probably just be a method on gdb.Frame.
-    # But then we need stream wrappers.
-    def describe (self, stream, full):
-        if self.frame.type () == gdb.DUMMY_FRAME:
-            stream.write (" <function called from gdb>\n")
-        elif self.frame.type () == gdb.SIGTRAMP_FRAME:
-            stream.write (" <signal handler called>\n")
-        else:
-            sal = self.frame.find_sal ()
-            pc = self.frame.pc ()
-            name = self.frame.name ()
-            if not name:
-                name = "??"
-            if pc != sal.pc or not sal.symtab:
-                stream.write (" 0x%08x in" % pc)
-            stream.write (" " + name + " (")
-
-            func = self.frame.function ()
-            self.print_frame_args (stream, func)
-
-            stream.write (")")
-
-            if sal.symtab and sal.symtab.filename:
-                stream.write (" at " + sal.symtab.filename)
-                stream.write (":" + str (sal.line))
-
-            if not self.frame.name () or (not sal.symtab or not sal.symtab.filename):
-                lib = gdb.solib_address (pc)
-                if lib:
-                    stream.write (" from " + lib)
-
-            stream.write ("\n")
-
-            if full:
-                self.print_frame_locals (stream, func)
-
-    def __getattr__ (self, name):
-        return getattr (self.frame, name)
-
 class ReverseBacktraceParameter (gdb.Parameter):
     """The new-backtrace command can show backtraces in 'reverse' order.
 This means that the innermost frame will be printed last.
diff --git a/gdb/python/lib/gdb/command/upto.py b/gdb/python/lib/gdb/command/upto.py
new file mode 100644
index 0000000..faf54ed
--- /dev/null
+++ b/gdb/python/lib/gdb/command/upto.py
@@ -0,0 +1,129 @@
+# upto command.
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gdb
+import re
+from gdb.FrameIterator import FrameIterator
+from gdb.FrameWrapper import FrameWrapper
+
+class UptoPrefix (gdb.Command):
+    def __init__ (self):
+        super (UptoPrefix, self).__init__ ("upto", gdb.COMMAND_STACK,
+                                           prefix = True)
+
+class UptoImplementation (gdb.Command):
+    def __init__ (self, subcommand):
+        super (UptoImplementation, self).__init__ ("upto " + subcommand,
+                                                   gdb.COMMAND_STACK)
+
+    def search (self):
+        saved = gdb.selected_frame ()
+        iter = FrameIterator (saved)
+        found = False
+        try:
+            for frame in iter:
+                frame.select ()
+                try:
+                    if self.filter (frame):
+                        wrapper = FrameWrapper (frame)
+                        wrapper.describe (sys.stdout, False)
+                        return
+                except:
+                    pass
+        except:
+            pass
+        saved.select ()
+        raise RuntimeError, 'Could not find a matching frame'
+
+    def invoke (self, arg, from_tty):
+        self.rx = re.compile (arg)
+        self.search ()
+
+class UptoSymbolCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on symbol.
+The argument is a regular expression.  This command moves up the
+stack, stopping at the first frame whose symbol matches the regular
+expression."""
+
+    def __init__ (self):
+        super (UptoSymbolCommand, self).__init__ ("symbol")
+
+    def filter (self, frame):
+        name = frame.name ()
+        if name is not None:
+            if self.rx.search (name) is not None:
+                return True
+        return False
+
+class UptoSourceCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on source file.
+The argument is a regular expression.  This command moves up the
+stack, stopping at the first frame whose source file name matches the
+regular expression."""
+
+    def __init__ (self):
+        super (UptoSourceCommand, self).__init__ ("source")
+
+    def filter (self, frame):
+        name = frame.find_sal ().symtab.filename
+        if name is not None:
+            if self.rx.search (name) is not None:
+                return True
+        return False
+
+class UptoObjectCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on object file.
+The argument is a regular expression.  This command moves up the
+stack, stopping at the first frame whose object file name matches the
+regular expression."""
+
+    def __init__ (self):
+        super (UptoObjectCommand, self).__init__ ("object")
+
+    def filter (self, frame):
+        name = frame.find_sal ().symtab.objfile.filename
+        if name is not None:
+            if self.rx.search (name) is not None:
+                return True
+        return False
+
+class UptoWhereCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on expression.
+The argument is an expression.  This command moves up the stack,
+parsing and evaluating the expression in each frame.  This stops when
+the expression evaluates to a non-zero (true) value."""
+
+    def __init__ (self):
+        super (UptoWhereCommand, self).__init__ ("where")
+
+    def filter (self, frame):
+        try:
+            if gdb.parse_and_eval (self.expression):
+                return True
+        except:
+            pass
+        return False
+
+    def invoke (self, arg, from_tty):
+        self.expression = arg
+        self.search ()
+
+UptoPrefix ()
+UptoSymbolCommand ()
+UptoSourceCommand ()
+UptoObjectCommand ()
+UptoWhereCommand ()
diff --git a/gdb/python/python-frame.c b/gdb/python/python-frame.c
index 229ba30..3d2f61f 100644
--- a/gdb/python/python-frame.c
+++ b/gdb/python/python-frame.c
@@ -440,6 +440,25 @@ frapy_read_var (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* Select this frame.  */
+
+static PyObject *
+frapy_select (PyObject *self, PyObject *args)
+{
+  struct frame_info *fi;
+  frame_object *frame = (frame_object *) self;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID (frame, fi);
+      select_frame (fi);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  Py_RETURN_NONE;
+}
+
 /* Implementation of gdb.selected_frame () -> gdb.Frame.
    Returns the selected frame object.  */
 
@@ -577,6 +596,8 @@ Return the frame's symtab and line." },
   { "read_var", frapy_read_var, METH_VARARGS,
     "read_var (variable) -> gdb.Value.\n\
 Return the value of the variable in this frame." },
+  { "select", frapy_select, METH_NOARGS,
+    "Select this frame as the user's current frame." },
   {NULL}  /* Sentinel */
 };
 
diff --git a/gdb/python/python-symtab.c b/gdb/python/python-symtab.c
index a48c38c..830e586 100644
--- a/gdb/python/python-symtab.c
+++ b/gdb/python/python-symtab.c
@@ -1,6 +1,6 @@
 /* Python interface to symbol tables.
 
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -78,6 +78,15 @@ stpy_get_filename (PyObject *self, void *closure)
 }
 
 static PyObject *
+stpy_get_objfile (PyObject *self, void *closure)
+{
+  symtab_object *self_symtab = (symtab_object *) self;
+  PyObject *result = objfile_to_objfile_object (self_symtab->symtab->objfile);
+  Py_INCREF (result);
+  return result;
+}
+
+static PyObject *
 stpy_fullname (PyObject *self, PyObject *args)
 {
   char *fullname;
@@ -225,6 +234,8 @@ gdbpy_initialize_symtabs (void)
 static PyGetSetDef symtab_object_getset[] = {
   { "filename", stpy_get_filename, NULL,
     "The symbol table's source filename.", NULL },
+  { "objfile", stpy_get_objfile, NULL, "The symtab's objfile.",
+    NULL },
   {NULL}  /* Sentinel */
 };
 


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-07-07 16:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-07 16:19 [SCM] archer-tromey-python: 'upto' commands tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).