This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[python] [patch] Add is_valid to several classes


This patch adds the is_valid API to all the remaining objects that have
lifetimes independent of the whole GDB session.  This allows the user
to safely test the validity of an object with out actually generating an
exception in the process.

OK?

Cheers,

Phil

--

2011-03-16  Phil Muldoon  <pmuldoon@redhat.com>

	* python/py-symtab.c: Populate symtab_object_methods,
	sal_object_methods.
	(stpy_is_valid): New function.
	(salpy_is_valid): Ditto.
	* python/py-symbol.c: Declare symbol_object_methods.  Populate.
	(sympy_is_valid): New function.
	* python/py-objfile.c: Declare objfile_object_methods.  Populate.
	(OBJFPY_REQUIRE_VALID): New macro.
	(OBJFPY_SET_REQUIRE_VALID):  Ditto.
	(objfpy_get_filename): Use OBJFPY_REQUIRE_VALID.
	(objfpy_get_printers): Ditto.
	(objfpy_set_printers): Use OBJFPY_SET_REQUIRE_VALID.
	(objfpy_is_valid): New function.
	* python/py-inferior.c: Populate inferior_object_methods.
	(infpy_is_valid): New function.
	* python/py-infthread.c: Populate thread_object_methods.
	(thpy_is_valid): New function.
	* python/py-block.c: Declare block_object_methods.  Populate.  Declare
	block_iterator_object_methods.  Populate.
	(blpy_is_valid): New function.
	(blpy_iter_is_valid): Ditto.

2011-03-16  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.texinfo (Blocks In Python): Add is_valid method description.
	(Inferiors In Python): Likewise.
	(Threads In Python): Likewise.
	(Symbols In Python): Likewise.
	(Objfiles In Python): Likewise.
	(Symbol Tables In Python): Likewise.

2010-03-16  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.python/Makefile.in: Add py-objfile.
	* gdb.python/py-objfile.exp: New file.
	* gdb.python/py-objfile.c: New file.
	* gdb.python/py-block.exp: Add is_valid tests.
	* gdb.python/py-inferior.exp: Ditto.
	* gdb.python/py-infthread.exp: Ditto.
	* gdb.python/py-symbol.exp: Ditto.
	* gdb.python/py-symtab.exp: Ditto.

--

diff --git a/gdb/NEWS b/gdb/NEWS
index c602fbe..22a474e 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -38,6 +38,10 @@
 
 * Python scripting
 
+  ** Symbols, Symbol Table, Symbol Table and Line, Object Files,
+     Inferior, Inferior Thread, Blocks, and Block Iterator APIs now
+     have an is_valid method.
+
   ** Breakpoints can now be sub-classed in Python, and in particular
      you may implement a 'stop' function that is executed each time
      the inferior reaches that breakpoint.   
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 01455d1..04c4656 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -21858,6 +21858,14 @@ started by @value{GDBN} itself.
 A @code{gdb.Inferior} object has the following methods:
 
 @table @code
+@defmethod Inferior is_valid
+Returns true if the @code{gdb.Inferior} object is valid, false if
+not.  A @code{gdb.Inferior} object will become invalid if the inferior
+no longer exists within @value{GDBN}.  All @code{gdb.Inferior}
+methods will throw an exception if it is invalid at the time the
+method is called.
+@end defmethod
+
 @defmethod Inferior threads
 This method returns a tuple holding all the threads which are valid
 when it is called.  If there are no valid threads, the method will
@@ -22057,6 +22065,14 @@ does not  use that identifier.
 A @code{gdb.InferiorThread} object has the following methods:
 
 @table @code
+@defmethod InferiorThread is_valid
+Returns true if the @code{gdb.InferiorThread} object is valid, false
+if not.  A @code{gdb.InferiorThread} object will become invalid if the
+thread exits, or the inferior that the thread belongs is deleted.  All
+@code{gdb.InferiorThread} methods will throw an exception if it is
+invalid at the time the method is called.
+@end defmethod
+
 @defmethod InferiorThread switch
 This changes @value{GDBN}'s currently selected thread to the one represented
 by this object.
@@ -22650,6 +22666,16 @@ which is used to format the value.  @xref{Pretty Printing API}, for more
 information.
 @end defivar
 
+A @code{gdb.Objfile} object has the following methods:
+
+@defmethod Objfile is_valid
+Returns true if the @code{gdb.Objfile} object is valid, false if not.
+A @code{gdb.Objfile} object can become invalid if the object file it
+refers to does not exist in @value{GDBN} any longer.  All
+@code{gdb.Objfile} methods will throw an exception if it is invalid at
+the time the method is called.
+@end defmethod
+
 @node Frames In Python
 @subsubsection Accessing inferior stack frames from Python.
 
@@ -22801,6 +22827,19 @@ block cannot be found for the @var{pc} value specified, the function
 will return @code{None}.
 @end defun
 
+A @code{gdb.Block} object has the following methods:
+
+@table @code
+@defmethod Block is_valid
+Returns true if the @code{gdb.Block} object is valid, false if not. A
+block object can become invalid if the block it refers to doesn't
+exist anymore in the inferior.  All @code{gdb.Block} methods will
+throw an exception if it is invalid at the time the method is called.
+This method is also made available to the Python iterator object that
+@code{gdb.Block} supports via the Python method @code{iter} function.
+@end defmethod
+@end table
+
 A @code{gdb.Block} object has the following attributes:
 
 @table @code
@@ -22923,6 +22962,18 @@ of a symbol.  Each address class is a constant defined in the
 @end defivar
 @end table
 
+A @code{gdb.Symbol} object has the following methods:
+
+@table @code
+@defmethod Symbol is_valid
+Returns true if the @code{gdb.Symbol} object is valid, false if not.
+A @code{gdb.Symbol} object can become invalid if the symbol it refers
+to does not exist in @value{GDBN} any longer.  All @code{gdb.Symbol}
+methods will throw an exception if it is invalid at the time the
+method is called.
+@end defmethod
+@end table
+
 The available domain categories in @code{gdb.Symbol} are represented
 as constants in the @code{gdb} module:
 
@@ -23067,6 +23118,18 @@ attribute is not writable.
 @end defivar
 @end table
 
+A @code{gdb.Symtab_and_line} object has the following methods:
+
+@table @code
+@defmethod Symtab_and_line is_valid
+Returns true if the @code{gdb.Symtab_and_line} object is valid, false
+if not.  A @code{gdb.Symtab_and_line} object can become invalid if the
+Symbol table and line object it refers to does not exist in
+@value{GDBN} any longer.  All @code{gdb.Symtab_and_line} methods will
+throw an exception if it is invalid at the time the method is called.
+@end defmethod
+@end table
+
 A @code{gdb.Symtab} object has the following attributes:
 
 @table @code
@@ -23080,9 +23143,17 @@ This attribute is not writable.
 @end defivar
 @end table
 
-The following methods are provided:
+A @code{gdb.Symtab} object has the following methods:
 
 @table @code
+@defmethod Symtab is_valid
+Returns true if the @code{gdb.Symtab} object is valid, false if not.
+A @code{gdb.Symtab} object can become invalid if the symbol table it
+refers to does not exist in @value{GDBN} any longer.  All
+@code{gdb.Symtab} methods will throw an exception if it is invalid at
+the time the method is called.
+@end defmethod
+
 @defmethod Symtab fullname
 Return the symbol table's source absolute file name.
 @end defmethod
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index 9d0d6cc..08d4455 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -263,6 +263,36 @@ blpy_block_syms_dealloc (PyObject *obj)
   Py_XDECREF (iter_obj->source);
 }
 
+/* Implementation of gdb.Block.is_valid (self) -> Boolean.
+   Returns True if this block object still exists in GDB.  */
+
+static PyObject *
+blpy_is_valid (PyObject *self, PyObject *args)
+{
+  struct block *block;
+
+  block = block_object_to_block (self);
+  if (block == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
+/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
+   Returns True if this block iterator object still exists in GDB  */
+
+static PyObject *
+blpy_iter_is_valid (PyObject *self, PyObject *args)
+{
+  block_syms_iterator_object *iter_obj =
+    (block_syms_iterator_object *) self;
+
+  if (iter_obj->source->block == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
 /* Return the innermost lexical block containing the specified pc value,
    or 0 if there is none.  */
 PyObject *
@@ -342,6 +372,13 @@ gdbpy_initialize_blocks (void)
 
 
 
+static PyMethodDef block_object_methods[] = {
+  { "is_valid", blpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this block is valid, false if not." },
+  {NULL}  /* Sentinel */
+};
+
 static PyGetSetDef block_object_getset[] = {
   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
@@ -381,11 +418,18 @@ PyTypeObject block_object_type = {
   0,				  /* tp_weaklistoffset */
   blpy_iter,			  /* tp_iter */
   0,				  /* tp_iternext */
-  0,				  /* tp_methods */
+  block_object_methods,		  /* tp_methods */
   0,				  /* tp_members */
   block_object_getset		  /* tp_getset */
 };
 
+static PyMethodDef block_iterator_object_methods[] = {
+  { "is_valid", blpy_iter_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this block iterator is valid, false if not." },
+  {NULL}  /* Sentinel */
+};
+
 static PyTypeObject block_syms_iterator_object_type = {
   PyObject_HEAD_INIT (NULL)
   0,				  /*ob_size*/
@@ -415,5 +459,5 @@ static PyTypeObject block_syms_iterator_object_type = {
   0,				  /*tp_weaklistoffset */
   blpy_block_syms_iter,           /*tp_iter */
   blpy_block_syms_iternext,	  /*tp_iternext */
-  0				  /*tp_methods */
+  block_iterator_object_methods   /*tp_methods */
 };
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index ee41ea7..b9df394 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -606,6 +606,20 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
     Py_RETURN_NONE;
 }
 
+/* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
+   Returns True if this inferior object still exists in GDB.  */
+
+static PyObject *
+infpy_is_valid (PyObject *self, PyObject *args)
+{
+  inferior_object *inf = (inferior_object *) self;
+
+  if (! inf->inferior)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
 
 /* Clear the INFERIOR pointer in an Inferior object and clear the
    thread list.  */
@@ -676,6 +690,9 @@ static PyGetSetDef inferior_object_getset[] =
 
 static PyMethodDef inferior_object_methods[] =
 {
+  { "is_valid", infpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this inferior is valid, false if not." },
   { "threads", infpy_threads, METH_NOARGS,
     "Return all the threads of this inferior." },
   { "read_memory", (PyCFunction) infpy_read_memory,
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index 059422d..b37c53c 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -222,7 +222,20 @@ thpy_is_exited (PyObject *self, PyObject *args)
   Py_RETURN_FALSE;
 }
 
+/* Implementation of gdb.InfThread.is_valid (self) -> Boolean.
+   Returns True if this inferior Thread object still exists
+   in GDB.  */
 
+static PyObject *
+thpy_is_valid (PyObject *self, PyObject *args)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  if (! thread_obj->thread)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
 
 /* Implementation of gdb.selected_thread () -> gdb.InferiorThread.
    Returns the selected thread object.  */
@@ -269,6 +282,9 @@ static PyGetSetDef thread_object_getset[] =
 
 static PyMethodDef thread_object_methods[] =
 {
+  { "is_valid", thpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this inferior thread is valid, false if not." },
   { "switch", thpy_switch, METH_NOARGS,
     "switch ()\n\
 Makes this the GDB selected thread." },
diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
index 7f9d9ee..7052bac 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -40,6 +40,31 @@ static const struct objfile_data *objfpy_objfile_data_key;
 
 
 
+/* Require that OBJFILE be a valid object file.  */
+
+#define OBJFPY_REQUIRE_VALID(Objfile)				\
+  do {								\
+    if (!Objfile->objfile)					\
+      {								\
+	PyErr_SetString (PyExc_RuntimeError,			\
+			 _("Object file no longer exists."));	\
+	return NULL;						\
+      }								\
+  } while (0)
+
+/* Require that OBJFILE be a valid object file.  This macro is used
+   for 'set' functions.  */
+
+#define OBJFPY_SET_REQUIRE_VALID(Objfile)			\
+  do {								\
+    if (!Objfile->objfile)					\
+      {								\
+	PyErr_SetString (PyExc_RuntimeError,			\
+			 _("Object file no longer exists."));	\
+	return -1;						\
+      }								\
+  } while (0)
+
 /* An Objfile method which returns the objfile's file name, or None.  */
 static PyObject *
 objfpy_get_filename (PyObject *self, void *closure)
@@ -85,6 +110,8 @@ objfpy_get_printers (PyObject *o, void *ignore)
 {
   objfile_object *self = (objfile_object *) o;
 
+  OBJFPY_REQUIRE_VALID (self);
+
   Py_INCREF (self->printers);
   return self->printers;
 }
@@ -95,6 +122,8 @@ objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
   PyObject *tmp;
   objfile_object *self = (objfile_object *) o;
 
+  OBJFPY_SET_REQUIRE_VALID (self);
+
   if (! value)
     {
       PyErr_SetString (PyExc_TypeError,
@@ -118,6 +147,20 @@ objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
   return 0;
 }
 
+/* Implementation of gdb.Objfile.is_valid (self) -> Boolean.
+   Returns True if this object file still exists in GDB.  */
+
+static PyObject *
+objfpy_is_valid (PyObject *self, PyObject *args)
+{
+  objfile_object *obj = (objfile_object *) self;
+
+  if (! obj->objfile)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
 
 
 /* Clear the OBJFILE pointer in an Objfile object and remove the
@@ -181,6 +224,15 @@ gdbpy_initialize_objfile (void)
 
 
 
+static PyMethodDef objfile_object_methods[] =
+{
+  { "is_valid", objfpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this object file is valid, false if not." },
+
+  { NULL }
+};
+
 static PyGetSetDef objfile_getset[] =
 {
   { "filename", objfpy_get_filename, NULL,
@@ -220,7 +272,7 @@ static PyTypeObject objfile_object_type =
   0,				  /* tp_weaklistoffset */
   0,				  /* tp_iter */
   0,				  /* tp_iternext */
-  0,				  /* tp_methods */
+  objfile_object_methods,	  /* tp_methods */
   0,				  /* tp_members */
   objfile_getset,		  /* tp_getset */
   0,				  /* tp_base */
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 2df2336..2c7900f 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -167,6 +167,21 @@ sympy_is_variable (PyObject *self, void *closure)
 			      || class == LOC_OPTIMIZED_OUT));
 }
 
+/* Implementation of gdb.Symbol.is_valid (self) -> Boolean.
+   Returns True if this Symbol still exists in GDB.  */
+
+static PyObject *
+sympy_is_valid (PyObject *self, PyObject *args)
+{
+  struct symbol *symbol = NULL;
+
+  symbol = symbol_object_to_symbol (self);
+  if (symbol == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
 /* Given a symbol, and a symbol_object that has previously been
    allocated and initialized, populate the symbol_object with the
    struct symbol data.  Also, register the symbol_object life-cycle
@@ -420,6 +435,13 @@ to display demangled or mangled names.", NULL },
   { NULL }  /* Sentinel */
 };
 
+static PyMethodDef symbol_object_methods[] = {
+  { "is_valid", sympy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this symbol is valid, false if not." },
+  {NULL}  /* Sentinel */
+};
+
 PyTypeObject symbol_object_type = {
   PyObject_HEAD_INIT (NULL)
   0,				  /*ob_size*/
@@ -449,7 +471,7 @@ PyTypeObject symbol_object_type = {
   0,				  /*tp_weaklistoffset */
   0,				  /*tp_iter */
   0,				  /*tp_iternext */
-  0,				  /*tp_methods */
+  symbol_object_methods,	  /*tp_methods */
   0,				  /*tp_members */
   symbol_object_getset		  /*tp_getset */
 };
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index 5c1c6bb..107cdec 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -138,6 +138,21 @@ stpy_fullname (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* Implementation of gdb.Symtab.is_valid (self) -> Boolean.
+   Returns True if this Symbol table still exists in GDB.  */
+
+static PyObject *
+stpy_is_valid (PyObject *self, PyObject *args)
+{
+  struct symtab *symtab = NULL;
+
+  symtab = symtab_object_to_symtab (self);
+  if (symtab == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
 static PyObject *
 salpy_str (PyObject *self)
 {
@@ -212,6 +227,21 @@ salpy_get_symtab (PyObject *self, void *closure)
   return (PyObject *) self_sal->symtab;
 }
 
+/* Implementation of gdb.Symtab_and_line.is_valid (self) -> Boolean.
+   Returns True if this Symbol table and line object still exists GDB.  */
+
+static PyObject *
+salpy_is_valid (PyObject *self, PyObject *args)
+{
+  struct symtab_and_line *sal;
+
+  sal = sal_object_to_symtab_and_line (self);
+  if (sal == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
 static void
 salpy_dealloc (PyObject *self)
 {
@@ -441,6 +471,9 @@ static PyGetSetDef symtab_object_getset[] = {
 };
 
 static PyMethodDef symtab_object_methods[] = {
+  { "is_valid", stpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this symbol table is valid, false if not." },
   { "fullname", stpy_fullname, METH_NOARGS,
     "fullname () -> String.\n\
 Return the symtab's full source filename." },
@@ -489,6 +522,13 @@ static PyGetSetDef sal_object_getset[] = {
   {NULL}  /* Sentinel */
 };
 
+static PyMethodDef sal_object_methods[] = {
+  { "is_valid", salpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this symbol table and line is valid, false if not." },
+  {NULL}  /* Sentinel */
+};
+
 static PyTypeObject sal_object_type = {
   PyObject_HEAD_INIT (NULL)
   0,				  /*ob_size*/
@@ -518,7 +558,7 @@ static PyTypeObject sal_object_type = {
   0,				  /*tp_weaklistoffset */
   0,				  /*tp_iter */
   0,				  /*tp_iternext */
-  0,				  /*tp_methods */
+  sal_object_methods,		  /*tp_methods */
   0,				  /*tp_members */
   sal_object_getset		  /*tp_getset */
 };
diff --git a/gdb/testsuite/gdb.python/Makefile.in b/gdb/testsuite/gdb.python/Makefile.in
index 2b26fc8..5b2b7b0 100644
--- a/gdb/testsuite/gdb.python/Makefile.in
+++ b/gdb/testsuite/gdb.python/Makefile.in
@@ -4,7 +4,7 @@ srcdir = @srcdir@
 EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
 	py-symbol py-mi py-breakpoint py-inferior py-infthread \
 	py-shared python lib-types py-events py-evthreads py-frame \
-	py-pp-maint py-progspace py-section-script
+	py-pp-maint py-progspace py-section-script py-objfile
 
 MISCELLANEOUS = py-shared-sl.sl
 
diff --git a/gdb/testsuite/gdb.python/py-block.exp b/gdb/testsuite/gdb.python/py-block.exp
index c400df7..98b89d9 100644
--- a/gdb/testsuite/gdb.python/py-block.exp
+++ b/gdb/testsuite/gdb.python/py-block.exp
@@ -62,3 +62,20 @@ gdb_py_test_silent_cmd "python block = frame.block()" "Get Frame 2's block" 0
 gdb_test "python print block" "<gdb.Block object at $hex>" \
          "Check Frame 2's block not None"
 gdb_test "python print block.function" "main" "main block"
+
+
+# Test Block is_valid.  This must always be the last test in this
+# testcase as it unloads the object file.
+delete_breakpoints
+gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
+gdb_py_test_silent_cmd "python block = frame.block()" "Get Frame block" 0
+gdb_py_test_silent_cmd "python block_iter = iter (block)" "Get Frame block" 0
+gdb_test "python print block.is_valid()" "True" \
+         "Check block validity"
+gdb_test "python print block_iter.is_valid()" "True" \
+         "Check block validity"
+gdb_unload
+gdb_test "python print block.is_valid()" "False" \
+         "Check block validity"
+gdb_test "python print block_iter.is_valid()" "False" \
+         "Check block validity"
diff --git a/gdb/testsuite/gdb.python/py-inferior.exp b/gdb/testsuite/gdb.python/py-inferior.exp
index 138c0fb..42ca920 100644
--- a/gdb/testsuite/gdb.python/py-inferior.exp
+++ b/gdb/testsuite/gdb.python/py-inferior.exp
@@ -191,3 +191,23 @@ if [isnative] {
     gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, end_addr - start_addr, pattern)" \
       "${one_pattern_found}" "find pattern straddling chunk boundary"
 }
+
+# Test Inferior is_valid.  This must always be the last test in
+# this testcase as it kills the inferior.
+
+gdb_py_test_silent_cmd "python inf_list = gdb.inferiors()" "get initial list" 1
+gdb_test "python print len(inf_list)" "1" "Get inferior list length"
+gdb_test "python print inf_list\[0\].is_valid()" "True" \
+         "Check inferior validity"
+gdb_test "add-inferior" "Added inferior 2.*" "add empty inferior 2"
+gdb_py_test_silent_cmd "python inf_list = gdb.inferiors()" "get new list" 1
+gdb_test "python print len(inf_list)" "2" "Get inferior list length"
+gdb_test "python print inf_list\[0\].is_valid()" "True" \
+         "Check inferior validity"
+gdb_test "python print inf_list\[1\].is_valid()" "True" \
+         "Check inferior validity"
+gdb_test_no_output "remove-inferiors 2" "remove-inferiors 2"
+gdb_test "python print inf_list\[0\].is_valid()" "False" \
+         "Check inferior validity"
+gdb_test "python print inf_list\[1\].is_valid()" "True" \
+         "Check inferior validity"
diff --git a/gdb/testsuite/gdb.python/py-infthread.exp b/gdb/testsuite/gdb.python/py-infthread.exp
index bbec4ec..05539ae 100644
--- a/gdb/testsuite/gdb.python/py-infthread.exp
+++ b/gdb/testsuite/gdb.python/py-infthread.exp
@@ -64,3 +64,10 @@ gdb_test "python print gdb.selected_thread().name == name" "True" \
 gdb_test "python print 'result =', t0.is_stopped ()" " = True" "test InferiorThread.is_stopped"
 gdb_test "python print 'result =', t0.is_running ()" " = False" "test InferiorThread.is_running"
 gdb_test "python print 'result =', t0.is_exited ()" " = False" "test InferiorThread.is_exited"
+
+# Test InferiorThread is_valid.  This must always be the last test in
+# this testcase as it kills the inferior.
+
+gdb_test "python print 'result =', t0.is_valid ()" " = True" "test InferiorThread.is_valid"
+gdb_test_no_output "kill inferior 1" "kill inferior 1"
+gdb_test "python print 'result =', t0.is_valid ()" " = False" "test InferiorThread.is_valid"
diff --git a/gdb/testsuite/gdb.python/py-objfile.c b/gdb/testsuite/gdb.python/py-objfile.c
new file mode 100644
index 0000000..8add52c
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-objfile.c
@@ -0,0 +1,23 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 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/>.  */
+
+int
+main ()
+{
+  int some_var = 0;
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp
new file mode 100644
index 0000000..f86efb5
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-objfile.exp
@@ -0,0 +1,51 @@
+# Copyright (C) 2011 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/>.
+
+# This file is part of the GDB testsuite.  It tests the program space
+# support in Python.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+load_lib gdb-python.exp
+
+set testfile "py-objfile"
+set srcfile ${testfile}.c
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+if ![runto_main] then {
+    fail "Can't run to main"
+    return 0
+}
+
+gdb_py_test_silent_cmd "python sym = gdb.lookup_symbol(\"some_var\")" \
+    "Find a symbol in objfile" 1
+gdb_py_test_silent_cmd "python objfile = sym\[0\].symtab.objfile" \
+    "Get backing object file" 1
+
+gdb_test "python print objfile.filename" ".*py-objfile.*" \
+  "Get objfile validity"
+gdb_test "python print objfile.is_valid()" "True" \
+  "Get objfile validity"
+gdb_unload
+gdb_test "python print objfile.is_valid()" "False" \
+  "Get objfile validity after unload"
diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp
index b30c639..bb22485 100644
--- a/gdb/testsuite/gdb.python/py-symbol.exp
+++ b/gdb/testsuite/gdb.python/py-symbol.exp
@@ -128,3 +128,19 @@ gdb_test "python print cplusfunc.name" "SimpleClass::valueofi().*" "Test func.na
 gdb_test "python print cplusfunc.print_name" "SimpleClass::valueofi().*" "Test func.print_name"
 gdb_test "python print cplusfunc.linkage_name" "SimpleClass::valueofi().*" "Test func.linkage_name"
 gdb_test "python print cplusfunc.addr_class == gdb.SYMBOL_LOC_BLOCK" "True" "Test func.addr_class"
+
+# Test is_valid when the objfile is unloaded.  This must be the last
+# test as it unloads the object file in GDB.
+# Start with a fresh gdb.
+clean_restart ${testfile}
+if ![runto_main] then {
+    fail "Cannot run to main."
+    return 0
+}
+gdb_breakpoint [gdb_get_line_number "Break at end."]
+gdb_continue_to_breakpoint "Break at end."
+gdb_py_test_silent_cmd "python a = gdb.lookup_symbol(\'a\')" "Get variable a" 0
+gdb_test "python print a\[0\].is_valid()" "True" "Test symbol validity"
+delete_breakpoints
+gdb_unload
+gdb_test "python print a\[0\].is_valid()" "False" "Test symbol validity"
diff --git a/gdb/testsuite/gdb.python/py-symtab.exp b/gdb/testsuite/gdb.python/py-symtab.exp
index d22811d..c52f5ef 100644
--- a/gdb/testsuite/gdb.python/py-symtab.exp
+++ b/gdb/testsuite/gdb.python/py-symtab.exp
@@ -57,8 +57,16 @@ gdb_py_test_silent_cmd "python symtab = sal.symtab" "Get block" 0
 gdb_test "python print sal.symtab" "gdb/testsuite/gdb.python/py-symbol.c.*" "Test symtab"
 gdb_test "python print sal.pc" "${decimal}" "Test sal.pc"
 gdb_test "python print sal.line" "42" "Test sal.line"
+gdb_test "python print sal.is_valid()" "True" "Test sal.is_valid"
 
 # Test symbol table.
 gdb_test "python print symtab.filename" "testsuite/gdb.python/py-symbol.c.*" "Test symtab.filename"
 gdb_test "python print symtab.objfile" "<gdb.Objfile object at ${hex}>" "Test symtab.objfile"
 gdb_test "python print symtab.fullname()" "testsuite/gdb.python/py-symbol.c.*" "Test symtab.fullname"
+gdb_test "python print symtab.is_valid()" "True" "Test symtab.is_valid()"
+
+# Test is_valid when the objfile is unloaded.  This must be the last
+# test as it unloads the object file in GDB.
+gdb_unload
+gdb_test "python print sal.is_valid()" "False" "Test sal.is_valid"
+gdb_test "python print symtab.is_valid()" "False" "Test symtab.is_valid()"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]