public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-pmuldoon-python-breakpoints: Initial version of visible/invisible breakpoints from Python. Only CLI. Revert vector to linked list changes.
@ 2010-09-28 9:27 pmuldoon
0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2010-09-28 9:27 UTC (permalink / raw)
To: archer-commits
The branch, archer-pmuldoon-python-breakpoints has been updated
via 1accd8f5f0c491b18bcb9e222a189e664dc00c9d (commit)
from a95e04ca2ca8fdeae594811689a97427f9297c7e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 1accd8f5f0c491b18bcb9e222a189e664dc00c9d
Author: Phil Muldoon <pmuldoon@redhat.com>
Date: Tue Sep 28 10:25:56 2010 +0100
Initial version of visible/invisible breakpoints from Python. Only CLI.
Revert vector to linked list changes.
-----------------------------------------------------------------------
Summary of changes:
gdb/breakpoint.c | 21 +++--
gdb/breakpoint.h | 14 ++--
gdb/doc/gdb.texinfo | 15 +++-
gdb/python/py-breakpoint.c | 141 +++++++++++++++-------------
gdb/testsuite/gdb.python/py-breakpoint.exp | 24 +++++
5 files changed, 134 insertions(+), 81 deletions(-)
First 500 lines of diff:
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index c980d93..26cab2c 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -4947,7 +4947,8 @@ breakpoint_1 (int bnum, int allflag, int (*filter) (const struct breakpoint *))
if (filter && !filter (b))
continue;
- if (allflag || (user_settable_breakpoint (b) && breakpoint_visible (b)))
+ if (allflag || (user_settable_breakpoint (b)
+ && breakpoint_visible (b)))
{
int addr_bit, type_len;
@@ -5466,6 +5467,7 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
b->ops = NULL;
b->condition_not_parsed = 0;
b->visible = 1;
+
/* Add this breakpoint to the end of the chain
so that a list of breakpoints will come out in order
of increasing numbers. */
@@ -6923,7 +6925,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
char *cond_string,
enum bptype type, enum bpdisp disposition,
int thread, int task, int ignore_count,
- struct breakpoint_ops *ops, int from_tty,
+ struct breakpoint_ops *ops, int from_tty,
int enabled, int visible)
{
struct breakpoint *b = NULL;
@@ -6972,6 +6974,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
b->disposition = disposition;
b->pspace = sals.sals[0].pspace;
b->visible = visible;
+
if (type == bp_static_tracepoint)
{
struct static_tracepoint_marker marker;
@@ -7046,6 +7049,10 @@ Couldn't determine the static tracepoint marker to probe"));
b->ops = ops;
if (visible)
mention (b);
+ else
+ /* Just notify observers without printing. */
+ observer_notify_breakpoint_created (b->number);
+
}
/* Remove element at INDEX_TO_REMOVE from SAL, shifting other
@@ -7510,9 +7517,7 @@ create_new_breakpoint (struct gdbarch *gdbarch,
int pending = 0;
int not_found = 0;
int task = 0;
- int prev_bkpt_count = 0;
-
- prev_bkpt_count = breakpoint_count;
+ int prev_bkpt_count = breakpoint_count;
sals.sals = NULL;
sals.nelts = 0;
@@ -7705,7 +7710,6 @@ create_new_breakpoint (struct gdbarch *gdbarch,
b = set_raw_breakpoint_without_location (gdbarch, type_wanted);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
-
b->thread = -1;
b->addr_string = addr_string[0];
b->cond_string = NULL;
@@ -7724,6 +7728,9 @@ create_new_breakpoint (struct gdbarch *gdbarch,
if (visible)
mention (b);
+ else
+ /* Just notify observers without printing. */
+ observer_notify_breakpoint_created (b->number);
}
if (sals.nelts > 1)
@@ -7769,7 +7776,7 @@ create_breakpoint (struct gdbarch *gdbarch,
return create_new_breakpoint (gdbarch, arg, cond_string, thread,
parse_condition_and_thread, tempflag,
type_wanted, ignore_count,
- pending_break_support,
+ pending_break_support,
ops, from_tty, enabled, 1);
}
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 8315e76..3c3b5d0 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -878,13 +878,13 @@ extern int create_breakpoint (struct gdbarch *gdbarch, char *arg,
int enabled);
extern int create_new_breakpoint (struct gdbarch *gdbarch, char *arg,
- char *cond_string, int thread,
- int parse_condition_and_thread,
- int tempflag,
- enum bptype type_wanted,
- int ignore_count,
- enum auto_boolean pending_break_support,
- struct breakpoint_ops *ops,
+ char *cond_string, int thread,
+ int parse_condition_and_thread,
+ int tempflag,
+ enum bptype type_wanted,
+ int ignore_count,
+ enum auto_boolean pending_break_support,
+ struct breakpoint_ops *ops,
int from_tty,
int enabled,
int visible);
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 07f9ad6..7791d0c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -22520,7 +22520,7 @@ Return the symbol table's source absolute file name.
Python code can manipulate breakpoints via the @code{gdb.Breakpoint}
class.
-@defmethod Breakpoint __init__ spec @r{[}type@r{]} @r{[}wp_class@r{]}
+@defmethod Breakpoint __init__ spec @r{[}type@r{]} @r{[}wp_class@r{]} @r{[}visible@r{]}
Create a new breakpoint. @var{spec} is a string naming the
location of the breakpoint, or an expression that defines a
watchpoint. The contents can be any location recognized by the
@@ -22528,7 +22528,12 @@ watchpoint. The contents can be any location recognized by the
command. The optional @var{type} denotes the breakpoint to create
from the types defined later in this chapter. This argument can be
either: @code{BP_BREAKPOINT} or @code{BP_WATCHPOINT}. @var{type}
-defaults to @code{BP_BREAKPOINT}. The optional @var{wp_class}
+defaults to @code{BP_BREAKPOINT}. The optional @var{visible} argument
+allow the breakpoint to become invisible to the user. The breakpoint
+will neither be reported when created, or will it be enumerated in the
+output from @samp{info breakpoints} (but will be enumerated with the
+@samp{maint info breakpoints} command). The @var{visible} argument
+has no effect with watchpoints. The optional @var{wp_class}
argument defines the class of watchpoint to create, if @var{type} is
defined as @code{BP_WATCHPOINT}. If a watchpoint class is not
provided, it is assumed to be a @var{WP_WRITE} class.
@@ -22606,6 +22611,12 @@ determine the actual breakpoint type or use-case. This attribute is not
writable.
@end defivar
+@defivar Breakpoint visible
+This attribute holds the breakpoint's visibility flag --- the identifier used to
+determine whether the breakpoint is visible to the user when set, or
+when the @samp{info breakpoints} command is run. This attribute is writable.
+@end defivar
+
The available types are represented by constants defined in the @code{gdb}
module:
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 2cbd751..e847092 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -34,6 +34,17 @@ typedef struct breakpoint_object breakpoint_object;
static PyTypeObject breakpoint_object_type;
+/* A dynamically allocated vector of breakpoint objects. Each
+ breakpoint has a number. A breakpoint is valid if its slot in this
+ vector is non-null. When a breakpoint is deleted, we drop our
+ reference to it and zero its slot; this is how we let the Python
+ object have a lifetime which is independent from that of the gdb
+ breakpoint. */
+static breakpoint_object **bppy_breakpoints;
+
+/* Number of slots in bppy_breakpoints. */
+static int bppy_slots;
+
/* Number of live breakpoints. */
static int bppy_live;
@@ -51,12 +62,8 @@ struct breakpoint_object
/* The gdb breakpoint object, or NULL if the breakpoint has been
deleted. */
struct breakpoint *bp;
- struct breakpoint_object *next;
};
-struct breakpoint_object *top;
-struct breakpoint_object *bottom;
-
/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
exception if it is invalid. */
#define BPPY_REQUIRE_VALID(Breakpoint) \
@@ -78,8 +85,6 @@ struct breakpoint_object *bottom;
} \
} while (0)
-#define ALL_PY_BREAKPOINTS(B) for (B = top; B; B = B->next)
-
/* This is used to initialize various gdb.bp_* constants. */
struct pybp_code
{
@@ -114,10 +119,9 @@ static struct pybp_code pybp_watch_types[] =
static int
bpnum_is_valid (int num)
{
- struct breakpoint *bp = NULL;
-
- bp = get_breakpoint (num);
- if (bp)
+ if (num >=0
+ && num < bppy_slots
+ && bppy_breakpoints[num] != NULL)
return 1;
return 0;
@@ -507,6 +511,29 @@ bppy_get_visibility (PyObject *self, void *closure)
return PyInt_FromLong (self_bp->bp->visible);
}
+/* Python function to set the 'silent' state of a breakpoint. */
+static int
+bppy_set_visibility (PyObject *self, PyObject *newvalue, void *closure)
+{
+ breakpoint_object *self_bp = (breakpoint_object *) self;
+
+ BPPY_SET_REQUIRE_VALID (self_bp);
+
+ if (newvalue == NULL || ! PyBool_Check (newvalue))
+ {
+ PyErr_SetString (PyExc_TypeError,
+ _("Value must be True or False."));
+ return -1;
+ }
+
+ if (newvalue == Py_True)
+ self_bp->bp->visible = 1;
+ else
+ self_bp->bp->visible = 0;
+
+ return 0;
+}
+
/* Python function to get the breakpoint's number. */
static PyObject *
bppy_get_number (PyObject *self, void *closure)
@@ -590,9 +617,7 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
bppy_pending_object = (breakpoint_object *) result;
bppy_pending_object->number = -1;
bppy_pending_object->bp = NULL;
- /* We don't add the breakpoint to the linked-list yet as the GDB
- breakpoint has not yet been created. */
- bppy_pending_object->next = NULL;
+
TRY_CATCH (except, RETURN_MASK_ALL)
{
switch (type)
@@ -644,7 +669,6 @@ PyObject *
gdbpy_breakpoints (PyObject *self, PyObject *args)
{
PyObject *result;
- breakpoint_object *b;
if (bppy_live == 0)
Py_RETURN_NONE;
@@ -652,13 +676,16 @@ gdbpy_breakpoints (PyObject *self, PyObject *args)
result = PyTuple_New (bppy_live);
if (result)
{
- int out = 0;
- ALL_PY_BREAKPOINTS (b)
- {
- Py_INCREF (b);
- PyTuple_SetItem (result, out, (PyObject *) b);
- ++out;
- }
+ int i, out = 0;
+
+ for (i = 0; out < bppy_live; ++i)
+ {
+ if (! bppy_breakpoints[i])
+ continue;
+ Py_INCREF (bppy_breakpoints[i]);
+ PyTuple_SetItem (result, out, (PyObject *) bppy_breakpoints[i]);
+ ++out;
+ }
}
return result;
}
@@ -676,6 +703,9 @@ gdbpy_breakpoint_created (int num)
struct breakpoint *bp = NULL;
PyGILState_STATE state;
+ if (num < 0)
+ return;
+
bp = get_breakpoint (num);
if (! bp)
return;
@@ -687,6 +717,21 @@ gdbpy_breakpoint_created (int num)
&& bp->type != bp_access_watchpoint)
return;
+ if (num >= bppy_slots)
+ {
+ int old = bppy_slots;
+
+ bppy_slots = bppy_slots * 2 + 10;
+ bppy_breakpoints
+ = (breakpoint_object **) xrealloc (bppy_breakpoints,
+ (bppy_slots
+ * sizeof (breakpoint_object *)));
+ memset (&bppy_breakpoints[old], 0,
+ (bppy_slots - old) * sizeof (PyObject *));
+ }
+
+ ++bppy_live;
+
state = PyGILState_Ensure ();
if (bppy_pending_object)
@@ -700,29 +745,10 @@ gdbpy_breakpoint_created (int num)
{
newbp->number = num;
newbp->bp = bp;
- newbp->next = NULL;
+ bppy_breakpoints[num] = newbp;
Py_INCREF (newbp);
}
- else
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("Error while creating breakpoint from GDB."));
- return;
- }
-
- ++bppy_live;
-
- /* If this is the first breakpoint created, set the top and bottom
- of the linked list. */
- if (top == NULL)
- top = newbp;
-
- if (bottom)
- bottom->next = newbp;
- bottom = newbp;
-
-
/* Just ignore errors here. */
PyErr_Clear ();
@@ -735,28 +761,15 @@ static void
gdbpy_breakpoint_deleted (int num)
{
PyGILState_STATE state;
- breakpoint_object *b = NULL;
- breakpoint_object *prev = NULL;
state = PyGILState_Ensure ();
- ALL_PY_BREAKPOINTS (b)
- {
- if (b->number == num)
- {
- if (b == top)
- top = b->next;
- else
- prev->next = b->next;
- if (b == bottom)
- bottom = prev;
-
- b->bp = NULL;
- Py_DECREF (b);
- --bppy_live;
- break;
- }
- prev = b;
- }
+ if (bpnum_is_valid (num))
+ {
+ bppy_breakpoints[num]->bp = NULL;
+ Py_DECREF (bppy_breakpoints[num]);
+ bppy_breakpoints[num] = NULL;
+ --bppy_live;
+ }
PyGILState_Release (state);
}
@@ -776,9 +789,6 @@ gdbpy_initialize_breakpoints (void)
PyModule_AddObject (gdb_module, "Breakpoint",
(PyObject *) &breakpoint_object_type);
- top = NULL;
- bottom = NULL;
-
observer_attach_breakpoint_created (gdbpy_breakpoint_created);
observer_attach_breakpoint_deleted (gdbpy_breakpoint_deleted);
@@ -801,6 +811,7 @@ gdbpy_initialize_breakpoints (void)
pybp_watch_types[i].code) < 0)
return;
}
+
}
\f
@@ -840,7 +851,7 @@ or None if no condition set."},
"Commands of the breakpoint, as specified by the user."},
{ "type", bppy_get_type, NULL,
"Type of breakpoint."},
- { "visible", bppy_get_visibility, NULL,
+ { "visible", bppy_get_visibility, bppy_set_visibility,
"Whether the breakpoint is visible to the user."},
{ NULL } /* Sentinel. */
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp
index 07a7362..dc78a92 100644
--- a/gdb/testsuite/gdb.python/py-breakpoint.exp
+++ b/gdb/testsuite/gdb.python/py-breakpoint.exp
@@ -126,6 +126,30 @@ gdb_test "end"
gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" "Get Breakpoint List" 0
gdb_test "python print blist\[len(blist)-1\].commands" "print \"Command for breakpoint has been executed.\".*print result"
+# Start with a fresh gdb.
+clean_restart ${testfile}
+
+if ![runto_main] then {
+ fail "Cannot run to main."
+ return 0
+}
+
+# Test invisible breakpooints.
+delete_breakpoints
+set ibp_location [gdb_get_line_number "Break at multiply."]
+gdb_py_test_silent_cmd "python ibp = gdb.Breakpoint(\"$ibp_location\", visible=False)" "Set invisible breakpoint" 0
+gdb_py_test_silent_cmd "python ilist = gdb.breakpoints()" "Get Breakpoint List" 0
+gdb_test "python print ilist\[0\]" "<gdb.Breakpoint object at $hex>" "Check invisible bp obj exists"
+gdb_test "python print ilist\[0\].location" "py-breakpoint\.c:$ibp_location*" "Check breakpoint location"
+gdb_test "python print ilist\[0\].visible" "0" "Check breakpoint visibility"
+gdb_test "python print ilist\[0\].number == gdb.parse_and_eval(\"\$bpnum\")" "True" "Check that bpnum has been updated"
+gdb_test "info breakpoints" "No breakpoints or watchpoints.*" "Check info breakpoints does not show invisible breakpoints"
+gdb_test "maint info breakpoints" "py-breakpoint\.c:$ibp_location.*" "Check maint info breakpoints shows invisible breakpoints"
+gdb_py_test_silent_cmd "python ilist\[0\].visible = True" "Set visibility to True" 0
+gdb_test "info breakpoints" "py-breakpoint\.c:$ibp_location.*" "Check info breakpoints shows visible breakpoints"
+gdb_py_test_silent_cmd "python ilist\[0\].visible = False" "Set visibility to True" 0
+gdb_test "info breakpoints" "No breakpoints or watchpoints.*" "Check info breakpoints does not show invisible breakpoints"
+
# Watchpoints
# Start with a fresh gdb.
clean_restart ${testfile}
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-09-28 9:27 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-28 9:27 [SCM] archer-pmuldoon-python-breakpoints: Initial version of visible/invisible breakpoints from Python. Only CLI. Revert vector to linked list changes pmuldoon
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).