Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Kevin Pouget <kevin.pouget@gmail.com>
To: Tom Tromey <tromey@redhat.com>
Cc: gdb-patches@sourceware.org, pmuldoon@redhat.com,
		Eli Zaretskii <eliz@gnu.org>
Subject: Re: [PATCH] Add bp_location to Python interface
Date: Tue, 03 Apr 2012 10:35:00 -0000	[thread overview]
Message-ID: <CAPftXUJ4VqDsadmWYZ39qpyGd7UAV1G3iHkDkWkVKqyxGnSCqg@mail.gmail.com> (raw)
In-Reply-To: <87zkaxn9zf.fsf@fleche.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 4601 bytes --]

On Fri, Mar 30, 2012 at 9:51 PM, Tom Tromey <tromey@redhat.com> wrote:
>
> >>>>> "Kevin" == Kevin Pouget <kevin.pouget@gmail.com> writes:
>
> Kevin> ping
>
> I'm sorry about the long delay on this.

thanks for the follow-up, I've been busy as well and had no time to ping it.

> Kevin>  free_bp_location (struct bp_location *loc)
> [...]
> Kevin> +  gdbpy_bplocation_free (loc);
>
> I wonder whether tying these wrapper objects to the bp_location is
> really best.
>
> We do take this approach for many other objects exposed to Python, but
> those objects tend to be rather long-lived, and also to some extent
> visible across gdb -- as opposed to breakpoint locations, which are
> entirely managed by the breakpoint module.
>
> A different approach would be to instantiate and fill in the location
> objects when the 'location' method is called, and give them "copy"
> semantics instead.
>
> I'm not totally convinced either way, and I would like to know what you
> think about this.

I think it's a good idea, it avoids the confusion of "short life"
objects which can't be saved, etc.
Now, I state in the documentation that

> Breakpoint location
> objects represent the state of the breakpoint location at the time the method
> @code{Breakpoint.locations} is called, and will not be further updated.

which sounds better than the previous version

> Kevin> +@findex gdb.locations
> Kevin> +@defun gdb.locations ()
>
> The "gdb." here seems incorrect.
> This is a method on Breakpoint.

changed

> Kevin> +Return a tuple containing a sequence of @code{gdb.BpLocation}
> objects
>
> "tuple containing a sequence" sounds weird.  I would say just "a
> sequence" and not specify that it must be a tuple; it is commonplace in
> Python to operate on sequences generically, and we might as well leave
> ourselves whatever leeway we reasonably can.

changed, the original sentence doesn't really make sense to me, "a
tuple containing" was just redundant

> Kevin> +@defvar BpLocation.inferior
>
> Locations are really tied to program spaces, not inferiors.
> Offhand it seems to me that we should respect this in the API.

I'm not convinced here; actually, I'm not sure to understand the point
of the Progspaces class, in its current state at least; and there is
no (as far as I've seen) equivalent of
"find_inferior_for_program_space" in Py, so one of the key interest of
BpLocation would be unavailable ...

> Kevin> +bplocpy_breakpoint_deleted (struct breakpoint *b) {
>
> Wrong brace placement.

fixed

> Kevin> +  tuple = PyList_AsTuple (list);
> Kevin> +  Py_DECREF (list);
>
> In keeping with the doc change, you could just return the list here,
> rather than convert to a tuple.

the idea here was that a tuple is not mutable, whereas a list is -- ()
vs. []. I've removed the tuple, although although I'm not sure when
I'm supposed to use the List or the Tuple.

> Kevin> +gdb_test "py print len(gdb.breakpoints())" "1" "ensure that threre
> is only one BP"
>
> Typo, "threre".
> Also the line should be split, here and elsewhere in the .exp.

fixed

> Kevin> +# how to check address location ? != address(main)
>
> It is tricky due to prologues, but you could check the output of "info
> symbol" on the address and see that it is "main".

I've added a test going this way, but I'm not very happy with the implementation

> gdb_test "py gdb.execute('info symbol %s' % loc1.address)"  "main .* in section \.text.*" "verify location address"
because the exact result is "main + 15" ... but I don't know if there
is any better way to do it.



there's no regression against the current git tree on x86_64/F16

2012-03-04  Kevin Pouget  <kevin.pouget@st.com>

	Add bp_location to Python interface
	* Makefile.in (SUBDIR_PYTHON_OBS): Add py-bploc.o
	(SUBDIR_PYTHON_SRCS): Add python/py-bploc.c
	Add build rule for this file.
	* breakpoint.h (struct bploc_object): Forward declaration.
	(struct bp_location): Add py_bploc_obj.
	* python/py-bploc.c: New file.
	* python/py-breakpoint.c (bppy_locations): New function.
	(breakpoint_object_methods): New method binding: locations().
	* python/python-internal.h (bploc_object): New typedef.
	(bplocation_to_bplocation_object): New prototype.
	(gdbpy_initialize_bplocation): Likewise.
	
doc/
	Add bp_location to Python interface
	* gdb.texinfo (Breakpoints In Python): Document
	gdb.Breakpoint.locations and gdb.BpLocation.


testsuite/
	Add bp_location to Python interface
	* gdb.python/py-breakpoint.exp: Test gdb.BpLocation.

[-- Attachment #2: 0001-Add-gdb.BpLocation-to-Python-interface.patch --]
[-- Type: application/octet-stream, Size: 18784 bytes --]

From 98b63231ccbf93de89a9cb596ce9efee013ee536 Mon Sep 17 00:00:00 2001
From: Kevin Pouget <kevin.pouget@st.com>
Date: Wed, 18 May 2011 10:02:23 -0400
Subject: [PATCH] Add gdb.BpLocation to Python interface

---
 gdb/Makefile.in                            |    6 +
 gdb/NEWS                                   |    4 +
 gdb/breakpoint.h                           |    1 +
 gdb/doc/gdb.texinfo                        |   36 ++++
 gdb/python/py-bploc.c                      |  246 ++++++++++++++++++++++++++++
 gdb/python/py-breakpoint.c                 |   36 ++++
 gdb/python/python-internal.h               |    6 +
 gdb/python/python.c                        |    1 +
 gdb/testsuite/gdb.python/py-breakpoint.exp |   54 ++++++
 9 files changed, 390 insertions(+), 0 deletions(-)
 create mode 100644 gdb/python/py-bploc.c

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 44d76f2..784dc76 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -269,6 +269,7 @@ SUBDIR_PYTHON_OBS = \
 	py-auto-load.o \
 	py-block.o \
 	py-bpevent.o \
+	py-bploc.o \
 	py-breakpoint.o \
 	py-cmd.o \
 	py-continueevent.o \
@@ -301,6 +302,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-auto-load.c \
 	python/py-block.c \
 	python/py-bpevent.c \
+	python/py-bploc.c \
 	python/py-breakpoint.c \
 	python/py-cmd.c \
 	python/py-continueevent.c \
@@ -2037,6 +2039,10 @@ py-bpevent.o: $(srcdir)/python/py-bpevent.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-bpevent.c
 	$(POSTCOMPILE)
 
+py-bploc.o: $(srcdir)/python/py-bploc.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-bploc.c
+	$(POSTCOMPILE)
+
 py-breakpoint.o: $(srcdir)/python/py-breakpoint.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-breakpoint.c
 	$(POSTCOMPILE)
diff --git a/gdb/NEWS b/gdb/NEWS
index 5885d32..f24499e 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -32,6 +32,10 @@
   ** A new method 'referenced_value' on gdb.Value objects which can
      dereference pointer as well as C++ reference values.
 
+  ** A new method "gdb.Breakpoint.locations" has been added, as well as
+     the class gdb.BpLocation to provide further details about breakpoint
+     locations.
+
 * GDBserver now supports stdio connections.
   E.g. (gdb) target remote | ssh myhost gdbserver - hello
 
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index e0eeeaa..11e5cee 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -27,6 +27,7 @@
 struct value;
 struct block;
 struct breakpoint_object;
+struct bploc_object;
 struct get_number_or_range_state;
 struct thread_info;
 struct bpstats;
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 8002429..91c1e2c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -24601,6 +24601,42 @@ commands, separated by newlines.  If there are no commands, this
 attribute is @code{None}.  This attribute is not writable.
 @end defvar
 
+@findex Breakpoint.locations
+@defun Breakpoint.locations ()
+Return a sequence containing the @code{gdb.BpLocation} objects 
+(see below) associated with this breakpoint.  A breakpoint with no location
+is a pending breakpoint (@pxref{Set Breaks, , pending breakpoints}).
+@end defun
+
+A breakpoint location is represented by a @code{gdb.BpLocation} object,
+which offers the following attributes (all read only). Breakpoint location 
+objects represent the state of the breakpoint location at the time the method
+@code{Breakpoint.locations} is called, and will not be further updated.
+
+@defvar BpLocation.owner
+This attribute holds a reference to the @code{gdb.Breakpoint} object which
+owns this location.  This attribute is not writable.  From an implementation 
+point of view, there is a one-to-many relation between a breakpoint and
+its locations, even if two breakpoints are set at same address.
+@end defvar
+
+@defvar BpLocation.enabled
+This attribute indicates whether this location is currently enabled or not.
+This attribute is not writable.
+@end defvar
+
+@defvar BpLocation.inferior
+This attribute holds a reference to the @code{gdb.Inferior} object
+in which this breakpoint location has been inserted.  The value will be 
+@code{None} if there is no inferior associated with this location.   This 
+attribute is not writable.
+@end defvar
+
+@defvar BpLocation.address
+This attribute holds a @code{gdb.Value} object corresponding to the address 
+at which the breakpoint has been inserted.   This attribute is not writable.
+@end defvar
+
 @node Finish Breakpoints in Python
 @subsubsection Finish Breakpoints
 
diff --git a/gdb/python/py-bploc.c b/gdb/python/py-bploc.c
new file mode 100644
index 0000000..fdf5b05
--- /dev/null
+++ b/gdb/python/py-bploc.c
@@ -0,0 +1,246 @@
+/* Python interface to breakpoint locations.
+
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+
+#include "defs.h"
+#include "inferior.h"
+#include "python-internal.h"
+#include "observer.h"
+#include "gdbarch.h"
+
+struct bploc_object
+{
+  PyObject_HEAD
+
+  PyObject *inferior;
+  PyObject *owner;
+  int enabled;
+  PyObject *addr;
+};
+
+static PyTypeObject bploc_object_type;
+
+/* Dissociate the bp_location from the Python object.  */
+
+static void
+bplocpy_dealloc (PyObject *self)
+{
+  bploc_object *self_bploc = (bploc_object *) self;
+
+  Py_DECREF (self_bploc->inferior);
+  Py_DECREF (self_bploc->owner);
+  Py_DECREF (self_bploc->addr);
+
+  self->ob_type->tp_free (self);
+}
+
+/* Returns a bp_location object (gdb.BpLocation) holding the information of
+   LOC from GDB, or NULL in case of failure, with a Python exception set.  */
+
+PyObject *
+bplocation_to_bplocation_object (struct bp_location *loc)
+{
+  bploc_object *bploc_obj;
+  struct inferior *inferior;
+  volatile struct gdb_exception except;
+  struct value *addr = NULL; /* Initialize to appease gcc warning.  */
+
+  bploc_obj = PyObject_New (bploc_object, &bploc_object_type);
+  if (!bploc_obj)
+    return NULL;
+
+  bploc_obj->enabled = loc->enabled;
+
+  inferior = find_inferior_for_program_space (loc->pspace);
+  if (inferior)
+    bploc_obj->inferior = inferior_to_inferior_object (inferior);
+  else
+    bploc_obj->inferior = Py_None;
+
+  if (!bploc_obj->inferior)
+      return NULL;
+  Py_INCREF (bploc_obj->inferior);
+
+  /* Cannot fail, triggered from Breakpoint.locations.  */
+  if (loc->owner && loc->owner->py_bp_object)
+    bploc_obj->owner = (PyObject *) loc->owner->py_bp_object;
+  else
+    bploc_obj->owner = Py_None;
+  Py_INCREF (bploc_obj->owner);
+
+  /* Get the address Value object.  */
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      struct type *val_type = NULL; /* Initialize to appease gcc warning.  */
+
+      if (is_watchpoint (loc->owner))
+        {
+          struct watchpoint *wp = (struct watchpoint *) loc->owner;
+
+          if (wp->val)
+            val_type = value_type (wp->val);
+        }
+
+      if (!val_type)
+        val_type = builtin_type (python_gdbarch)->builtin_void;
+
+      addr = value_from_pointer (lookup_pointer_type (val_type),
+                                loc->address);
+    }
+  if (except.reason < 0)
+    {
+      gdbpy_convert_exception (except);
+      goto fail;
+    }
+
+  bploc_obj->addr = value_to_value_object (addr);
+  if (!bploc_obj->addr)
+    goto fail;
+
+  Py_INCREF (bploc_obj->addr);
+
+  return (PyObject *) bploc_obj;
+
+fail:
+  Py_XDECREF (bploc_obj->inferior);
+  Py_XDECREF (bploc_obj->owner);
+  return NULL;
+}
+
+/* Python function to get the BP owning this location.  */
+
+static PyObject *
+bplocpy_get_owner (PyObject *self, void *closure)
+{
+  bploc_object *self_bploc = (bploc_object *) self;
+
+  Py_INCREF (self_bploc->owner);
+
+  return self_bploc->owner;
+}
+
+/* Python function to test whether or not this breakpoint location is
+   enabled.  */
+
+static PyObject *
+bplocpy_get_enabled (PyObject *self, void *closure)
+{
+  bploc_object *self_bploc = (bploc_object *) self;
+
+  if (self_bploc->enabled)
+    Py_RETURN_TRUE;
+  else
+    Py_RETURN_FALSE;
+}
+
+/* Python function to get the address of this breakpoint location.  The
+   gdb.Value object will be cached if this is the first access.  */
+
+static PyObject *
+bplocpy_get_address (PyObject *self, void *closure)
+{
+  bploc_object *self_bploc = (bploc_object *) self;
+
+  Py_INCREF (self_bploc->addr);
+
+  return self_bploc->addr;
+}
+
+/* Python function to get the inferior hosting this breakpoint location.
+   Return Py_None if there is no inferior associated with the program space of
+   this location.  */
+
+static PyObject *
+bplocpy_get_inferior (PyObject *self, void *closure)
+{
+  bploc_object *self_bploc = (bploc_object *) self;
+
+  Py_INCREF (self_bploc->inferior);
+
+  return self_bploc->inferior;
+}
+
+/* Initialize the Python bp_location code.  */
+
+void
+gdbpy_initialize_bplocation (void)
+{
+  if (PyType_Ready (&bploc_object_type) < 0)
+    return;
+
+  Py_INCREF (&bploc_object_type);
+  PyModule_AddObject (gdb_module, "BpLocation", (PyObject *) &bploc_object_type);
+}
+
+static PyGetSetDef bploc_object_getset[] =
+{
+  { "owner", bplocpy_get_owner, NULL,
+    "Each breakpoint location must belong to exactly one higher-level \
+breakpoint.",
+    NULL },
+  { "enabled", bplocpy_get_enabled, NULL,
+    "Is this particular location enabled.", NULL },
+  { "address", bplocpy_get_address, NULL,
+    "The address at which the breakpoint has been set.", NULL },
+  { "inferior", bplocpy_get_inferior, NULL,
+    "The inferior in which this breakpoint location has been set.", NULL },
+  { NULL }  /* Sentinel.  */
+};
+
+static PyTypeObject bploc_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,                                          /* ob_size */
+  "gdb.BpLocation",                           /* tp_name */
+  sizeof (bploc_object),                      /* tp_basicsize */
+  0,                                          /* tp_itemsize */
+  bplocpy_dealloc,                            /* tp_dealloc */
+  0,                                          /* tp_print */
+  0,                                          /* tp_getattr */
+  0,                                          /* tp_setattr */
+  0,                                          /* tp_compare */
+  0,                                          /* tp_repr */
+  0,                                          /* tp_as_number */
+  0,                                          /* tp_as_sequence */
+  0,                                          /* tp_as_mapping */
+  0,                                          /* tp_hash  */
+  0,                                          /* tp_call */
+  0,                                          /* tp_str */
+  0,                                          /* tp_getattro */
+  0,                                          /* tp_setattro */
+  0,                                          /* tp_as_buffer */
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
+  "GDB breakpoint location object",           /* tp_doc */
+  0,                                          /* tp_traverse */
+  0,                                          /* tp_clear */
+  0,                                          /* tp_richcompare */
+  0,                                          /* tp_weaklistoffset */
+  0,                                          /* tp_iter */
+  0,                                          /* tp_iternext */
+  0,                                          /* tp_methods */
+  0,                                          /* tp_members */
+  bploc_object_getset,                        /* tp_getset */
+  0,                                          /* tp_base */
+  0,                                          /* tp_dict */
+  0,                                          /* tp_descr_get */
+  0,                                          /* tp_descr_set */
+  0,                                          /* tp_dictoffset */
+  0,                                          /* tp_init */
+  0                                           /* tp_alloc */
+};
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index b2c625f..3da5703 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -585,6 +585,40 @@ bppy_get_ignore_count (PyObject *self, void *closure)
   return PyInt_FromLong (self_bp->bp->ignore_count);
 }
 
+
+/* Python function which returns the BpLocation objects associated
+   with this breakpoint.  */
+
+static PyObject *
+bppy_locations (PyObject *self, PyObject *args)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  PyObject *list;
+  struct bp_location *loc;
+  int err;
+
+  BPPY_REQUIRE_VALID (self_bp);
+
+  list = PyList_New (0);
+  if (!list)
+    return NULL;
+
+  err = 0;
+  for (loc = self_bp->bp->loc; loc; loc = loc->next)
+    {
+      PyObject *loc_obj =  bplocation_to_bplocation_object (loc);
+      err = PyList_Append (list, loc_obj);
+      if (err == -1)
+        {
+          Py_DECREF (list);
+          return NULL;
+        }
+      Py_DECREF (loc_obj);
+    }
+
+  return list;
+}
+
 /* Python function to create a new breakpoint.  */
 static int
 bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
@@ -976,6 +1010,8 @@ static PyMethodDef breakpoint_object_methods[] =
     "Return true if this breakpoint is valid, false if not." },
   { "delete", bppy_delete_breakpoint, METH_NOARGS,
     "Delete the underlying GDB breakpoint." },
+  { "locations", bppy_locations, METH_NOARGS,
+    "Get a list of gdb.BpLocation objects associated with this breakpoint." },
   { NULL } /* Sentinel.  */
 };
 
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index bae61c2..e852bce 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -166,6 +166,9 @@ typedef struct breakpoint_object
 extern breakpoint_object *bppy_pending_object;
 
 
+/* Defined in py-bploc.c */
+typedef struct bploc_object bploc_object;
+
 typedef struct
 {
   PyObject_HEAD
@@ -218,6 +221,8 @@ PyObject *pspy_get_printers (PyObject *, void *);
 PyObject *objfile_to_objfile_object (struct objfile *);
 PyObject *objfpy_get_printers (PyObject *, void *);
 
+PyObject *bplocation_to_bplocation_object (struct bp_location *loc);
+
 thread_object *create_thread_object (struct thread_info *tp);
 thread_object *find_thread_object (ptid_t ptid);
 PyObject *find_inferior_object (int pid);
@@ -246,6 +251,7 @@ void gdbpy_initialize_pspace (void);
 void gdbpy_initialize_objfile (void);
 void gdbpy_initialize_breakpoints (void);
 void gdbpy_initialize_finishbreakpoints (void);
+void gdbpy_initialize_bplocation (void);
 void gdbpy_initialize_lazy_string (void);
 void gdbpy_initialize_parameters (void);
 void gdbpy_initialize_thread (void);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 938275a..df9deee 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1257,6 +1257,7 @@ message == an error message without a stack will be printed."),
   gdbpy_initialize_objfile ();
   gdbpy_initialize_breakpoints ();
   gdbpy_initialize_finishbreakpoints ();
+  gdbpy_initialize_bplocation ();
   gdbpy_initialize_lazy_string ();
   gdbpy_initialize_thread ();
   gdbpy_initialize_inferior ();
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp
index f3d409e..f6744e5 100644
--- a/gdb/testsuite/gdb.python/py-breakpoint.exp
+++ b/gdb/testsuite/gdb.python/py-breakpoint.exp
@@ -178,6 +178,15 @@ if ![runto_main] then {
 }
 
 gdb_py_test_silent_cmd  "python wp1 = gdb.Breakpoint (\"result\", type=gdb.BP_WATCHPOINT, wp_class=gdb.WP_WRITE )" "Set watchpoint" 0
+
+gdb_test "python print len(wp1.locations()) == 1" "True" \
+         "check watchpoint location"
+gdb_test "python print wp1.locations()\[0\].inferior.num" "1" \
+         "check watchpoint location's inferior"
+gdb_test "python print wp1.locations()\[0\].address    \
+            == gdb.parse_and_eval(\"&result\")" "True" \
+          "check watchpoint location's address"
+
 gdb_test "continue" ".*\[Ww\]atchpoint.*result.*Old value = 0.*New value = 25.*main.*" "Test watchpoint write"
 
 # Internal breakpoints.
@@ -300,3 +309,48 @@ gdb_py_test_silent_cmd  "python wp1 = wp_eval (\"result\", type=gdb.BP_WATCHPOIN
 gdb_test "continue" ".*\[Ww\]atchpoint.*result.*Old value =.*New value = 788.*" "Test watchpoint write"
 gdb_test "python print never_eval_bp1.count" "0" \
     "Check that this unrelated breakpoints eval function was never called."
+
+# gdb.BpLocation
+
+# Start with a fresh gdb.
+clean_restart ${testfile}
+
+if ![runto_main] then {
+    fail "Cannot run to main."
+    return 0
+}
+delete_breakpoints
+gdb_test_no_output "set detach-on-fork off" "don't detach on fork"
+gdb_test "call fork()" "New process .*" "create a second inferior"
+
+gdb_breakpoint "main"
+gdb_test "py print len(gdb.breakpoints())" "1" \
+         "ensure that there is only one BP"
+gdb_test_no_output {py bp0 = gdb.breakpoints()[0]} "save breakpoint 0"
+gdb_test "py print len(bp0.locations())" "2" \
+         "ensure that threre are 2 locations"
+
+gdb_test_no_output {py loc0 = bp0.locations()[0]} "save location 0"
+gdb_test_no_output {py loc1 = bp0.locations()[1]} "save location 1"
+
+gdb_test "py print loc0.owner == loc1.owner == bp0" "True" "verify ownership"
+gdb_test "py print loc0.address == loc1.address " "True" \
+         "verify addresses are identical"
+gdb_test "py gdb.execute('info symbol %s' % loc1.address)" \
+         "main .* in section \.text.*" "verify location address"
+
+gdb_test {py print loc0.inferior == gdb.inferiors()[0]} "True" \
+		 "verify inferior for loc 0" #inf 2
+gdb_test {py print loc1.inferior == gdb.inferiors()[1]} "True" \
+         "verify inferior for loc 1" #inf 1
+
+gdb_test "py print loc0.enabled == loc1.enabled == True" "True" \
+         "verify that locations are enabled"
+
+gdb_test "py print loc0.inferior.num" "2" "ensure that loc0 is on inferior 2"
+
+delete_breakpoints
+gdb_test "py print bp0.is_valid()" "False" \
+         "verify that BP has been invalidated"
+gdb_test "py bp0.locations()" ".*RuntimeError: Breakpoint .* is invalid.*"\
+         "verify that locations can't accessed on an invalid breakpoint"
-- 
1.7.7.6


  reply	other threads:[~2012-04-03 10:35 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-08 10:17 Kevin Pouget
2011-12-08 13:39 ` Phil Muldoon
2011-12-08 14:28   ` Kevin Pouget
2011-12-08 14:56 ` Phil Muldoon
2011-12-09 13:49   ` Kevin Pouget
2011-12-09 14:15     ` Phil Muldoon
2011-12-13 15:55       ` Kevin Pouget
2012-01-09 11:47         ` Kevin Pouget
2012-01-09 17:23           ` Eli Zaretskii
2012-01-10 15:09             ` Kevin Pouget
2012-01-10 16:03               ` Kevin Pouget
2012-01-10 17:25               ` Eli Zaretskii
2012-01-11 10:16                 ` Kevin Pouget
2012-01-11 10:27                   ` Eli Zaretskii
2012-01-10 22:24               ` Doug Evans
2012-01-11  9:05                 ` Kevin Pouget
2012-01-11 19:45                   ` Doug Evans
2012-01-27 13:04                     ` Kevin Pouget
2012-03-30 19:51                       ` Tom Tromey
2012-04-03 10:35                         ` Kevin Pouget [this message]
2012-04-03 12:15                           ` Phil Muldoon
2012-04-03 14:43                             ` Paul_Koning
2012-04-04  8:36                               ` Kevin Pouget
2012-05-09  7:18                                 ` Kevin Pouget
2012-04-05 16:27                           ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAPftXUJ4VqDsadmWYZ39qpyGd7UAV1G3iHkDkWkVKqyxGnSCqg@mail.gmail.com \
    --to=kevin.pouget@gmail.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=pmuldoon@redhat.com \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox