2010-11-11 Phil Muldoon <pmuldoon@redhat.com>

* python/py-breakpoint.c (BPPY_REQUIRE_VALID): Check if bp is
	NULL.
	(BPPY_SET_REQUIRE_VALID): Ditto.
	(bpnum_is_valid): Delete function.
	(bppy_get_visibility): New function.
	(bppy_new): Parse for, and validate internal keyword.  Pass
	internal keyword to breakpoint or watchpoint functions.
	(build_bp_list): New function.
	(gdbpy_breakpoints): Rewrite.  Use build_bp_list and
	iterate_over_breakpoints.
	(gdbpy_breakpoint_created): Rewrite.  Do not store breakpoints in a
	look-aside vector.
	(gdbpy_breakpoint_deleted): Rewrite, defer breakpoint management
	to internal breakpoint chain.

	* breakpoint.c (set_breakpoint_number): New function.
	(breakpoint_1): Check if breakpoint number is more than zero.
	(set_raw_breakpoint_without_location): Set py_bp_object to NULL.
	(create_breakpoint_sal): Take a new parameter called internal.
	Call set_breakpoint_number with internal parameter.  Do not
	mention internal breakpoints.  All callers updated.
	(create_breakpoint): Ditto.
	(create_breakpoints_sal): Ditto.
	(watch_command_1): Ditto.
	(watch_command_wrapper): Take a new parameter called internal.
	All callers updated.
	(rwatch_command_wrapper): Ditto.
	(awatch_command_wrapper): Ditto.
	(save_breakpoints): Update breakpoint save condition check.
	(iterate_over_breakpoints): New function.
	* breakpoint.h: Add conditional python includes.  Add py_bp_object
	and comment to struct breakpoint.  Update all callers.
	* defs.h: Add PyObject definition for GDB builds without Python.

2010-11-11  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.texinfo (Breakpoints In Python): Document "internal"
	parameter, and visible attribute.


2010-11-11  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.python/py-breakpoint.exp: Add internal watchpoint and
	breakpoint tests.
This commit is contained in:
Phil Muldoon 2010-11-11 14:11:56 +00:00
parent 95a2c8d6f7
commit 84f4c1fe05
12 changed files with 326 additions and 126 deletions

View File

@ -1,3 +1,39 @@
2010-11-11 Phil Muldoon <pmuldoon@redhat.com>
* python/py-breakpoint.c (BPPY_REQUIRE_VALID): Check if bp is
NULL.
(BPPY_SET_REQUIRE_VALID): Ditto.
(bpnum_is_valid): Delete function.
(bppy_get_visibility): New function.
(bppy_new): Parse for, and validate internal keyword. Pass
internal keyword to breakpoint or watchpoint functions.
(build_bp_list): New function.
(gdbpy_breakpoints): Rewrite. Use build_bp_list and
iterate_over_breakpoints.
(gdbpy_breakpoint_created): Rewrite. Do not store breakpoints in a
look-aside vector.
(gdbpy_breakpoint_deleted): Rewrite, defer breakpoint management
to internal breakpoint chain.
* breakpoint.c (set_breakpoint_number): New function.
(breakpoint_1): Check if breakpoint number is more than zero.
(set_raw_breakpoint_without_location): Set py_bp_object to NULL.
(create_breakpoint_sal): Take a new parameter called internal.
Call set_breakpoint_number with internal parameter. Do not
mention internal breakpoints. All callers updated.
(create_breakpoint): Ditto.
(create_breakpoints_sal): Ditto.
(watch_command_1): Ditto.
(watch_command_wrapper): Take a new parameter called internal.
All callers updated.
(rwatch_command_wrapper): Ditto.
(awatch_command_wrapper): Ditto.
(save_breakpoints): Update breakpoint save condition check.
(iterate_over_breakpoints): New function.
* breakpoint.h: Add conditional python includes. Add py_bp_object
and comment to struct breakpoint. Update all callers.
* defs.h: Add PyObject definition for GDB builds without Python.
2010-11-10 Doug Evans <dje@google.com>
* python/lib/gdb/command/pretty_printers.py

View File

@ -2068,6 +2068,24 @@ reattach_breakpoints (int pid)
static int internal_breakpoint_number = -1;
/* Set the breakpoint number of B, depending on the value of INTERNAL.
If INTERNAL is non-zero, the breakpoint number will be populated
from internal_breakpoint_number and that variable decremented.
Otherwis the breakpoint number will be populated from
breakpoint_count and that value incremented. Internal breakpoints
do not set the internal var bpnum. */
static void
set_breakpoint_number (int internal, struct breakpoint *b)
{
if (internal)
b->number = internal_breakpoint_number--;
else
{
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
}
}
static struct breakpoint *
create_internal_breakpoint (struct gdbarch *gdbarch,
CORE_ADDR address, enum bptype type)
@ -4939,7 +4957,8 @@ breakpoint_1 (int bnum, int allflag, int (*filter) (const struct breakpoint *))
if (filter && !filter (b))
continue;
if (allflag || user_settable_breakpoint (b))
if (allflag || (user_settable_breakpoint (b)
&& b->number > 0))
{
int addr_bit, type_len;
@ -5007,7 +5026,8 @@ breakpoint_1 (int bnum, int allflag, int (*filter) (const struct breakpoint *))
/* We only print out user settable breakpoints unless the
allflag is set. */
if (allflag || user_settable_breakpoint (b))
if (allflag || (user_settable_breakpoint (b)
&& b->number > 0))
print_one_breakpoint (b, &last_loc, print_address_bits, allflag);
}
}
@ -5456,6 +5476,7 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
b->syscalls_to_be_caught = NULL;
b->ops = NULL;
b->condition_not_parsed = 0;
b->py_bp_object = NULL;
/* Add this breakpoint to the end of the chain
so that a list of breakpoints will come out in order
@ -6914,7 +6935,8 @@ 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, int enabled)
struct breakpoint_ops *ops, int from_tty,
int enabled, int internal)
{
struct breakpoint *b = NULL;
int i;
@ -6951,8 +6973,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
if (i == 0)
{
b = set_raw_breakpoint (gdbarch, sal, type);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
set_breakpoint_number (internal, b);
b->thread = thread;
b->task = task;
@ -7034,7 +7055,12 @@ Couldn't determine the static tracepoint marker to probe"));
= xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));
b->ops = ops;
mention (b);
if (internal)
/* Do not mention breakpoints with a negative number, but do
notify observers. */
observer_notify_breakpoint_created (b->number);
else
mention (b);
}
/* Remove element at INDEX_TO_REMOVE from SAL, shifting other
@ -7190,7 +7216,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
enum bptype type, enum bpdisp disposition,
int thread, int task, int ignore_count,
struct breakpoint_ops *ops, int from_tty,
int enabled)
int enabled, int internal)
{
int i;
@ -7201,7 +7227,8 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
create_breakpoint_sal (gdbarch, expanded, addr_string[i],
cond_string, type, disposition,
thread, task, ignore_count, ops, from_tty, enabled);
thread, task, ignore_count, ops,
from_tty, enabled, internal);
}
}
@ -7470,8 +7497,10 @@ decode_static_tracepoint_spec (char **arg_p)
parameter. If non-zero, the function will parse arg, extracting
breakpoint location, address and thread. Otherwise, ARG is just the
location of breakpoint, with condition and thread specified by the
COND_STRING and THREAD parameters. Returns true if any breakpoint
was created; false otherwise. */
COND_STRING and THREAD parameters. If INTERNAL is non-zero, the
breakpoint number will be allocated from the internal breakpoint
count. Returns true if any breakpoint was created; false
otherwise. */
int
create_breakpoint (struct gdbarch *gdbarch,
@ -7481,8 +7510,7 @@ create_breakpoint (struct gdbarch *gdbarch,
int ignore_count,
enum auto_boolean pending_break_support,
struct breakpoint_ops *ops,
int from_tty,
int enabled)
int from_tty, int enabled, int internal)
{
struct gdb_exception e;
struct symtabs_and_lines sals;
@ -7658,12 +7686,15 @@ create_breakpoint (struct gdbarch *gdbarch,
cond_string, type_wanted,
tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops,
from_tty, enabled);
from_tty, enabled, internal);
do_cleanups (old_chain);
/* Get the tracepoint we just created. */
tp = get_breakpoint (breakpoint_count);
if (internal)
tp = get_breakpoint (internal_breakpoint_number);
else
tp = get_breakpoint (breakpoint_count);
gdb_assert (tp != NULL);
/* Given that its possible to have multiple markers with
@ -7679,7 +7710,7 @@ create_breakpoint (struct gdbarch *gdbarch,
create_breakpoints_sal (gdbarch, sals, addr_string, cond_string,
type_wanted, tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops, from_tty,
enabled);
enabled, internal);
}
else
{
@ -7688,8 +7719,7 @@ create_breakpoint (struct gdbarch *gdbarch,
make_cleanup (xfree, copy_arg);
b = set_raw_breakpoint_without_location (gdbarch, type_wanted);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
set_breakpoint_number (internal, b);
b->thread = -1;
b->addr_string = addr_string[0];
b->cond_string = NULL;
@ -7699,13 +7729,19 @@ create_breakpoint (struct gdbarch *gdbarch,
b->ops = ops;
b->enable_state = enabled ? bp_enabled : bp_disabled;
b->pspace = current_program_space;
b->py_bp_object = NULL;
if (enabled && b->pspace->executing_startup
&& (b->type == bp_breakpoint
|| b->type == bp_hardware_breakpoint))
b->enable_state = bp_startup_disabled;
mention (b);
if (internal)
/* Do not mention breakpoints with a negative number,
but do notify observers. */
observer_notify_breakpoint_created (b->number);
else
mention (b);
}
if (sals.nelts > 1)
@ -7750,7 +7786,8 @@ break_command_1 (char *arg, int flag, int from_tty)
pending_break_support,
NULL /* breakpoint_ops */,
from_tty,
1 /* enabled */);
1 /* enabled */,
0 /* internal */);
}
@ -8017,7 +8054,8 @@ watchpoint_exp_is_const (const struct expression *exp)
hw_read: watch read,
hw_access: watch access (read or write) */
static void
watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
watch_command_1 (char *arg, int accessflag, int from_tty,
int just_location, int internal)
{
struct breakpoint *b, *scope_breakpoint = NULL;
struct expression *exp;
@ -8225,8 +8263,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
/* Now set up the breakpoint. */
b = set_raw_breakpoint_without_location (NULL, bp_type);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
set_breakpoint_number (internal, b);
b->thread = thread;
b->disposition = disp_donttouch;
b->exp = exp;
@ -8285,8 +8322,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
/* Finally update the new watchpoint. This creates the locations
that should be inserted. */
update_watchpoint (b, 1);
mention (b);
if (internal)
/* Do not mention breakpoints with a negative number, but do
notify observers. */
observer_notify_breakpoint_created (b->number);
else
mention (b);
update_global_location_list (1);
}
@ -8370,9 +8411,9 @@ can_use_hardware_watchpoint (struct value *v)
}
void
watch_command_wrapper (char *arg, int from_tty)
watch_command_wrapper (char *arg, int from_tty, int internal)
{
watch_command_1 (arg, hw_write, from_tty, 0);
watch_command_1 (arg, hw_write, from_tty, 0, internal);
}
/* A helper function that looks for an argument at the start of a
@ -8408,7 +8449,7 @@ watch_maybe_just_location (char *arg, int accessflag, int from_tty)
just_location = 1;
}
watch_command_1 (arg, accessflag, from_tty, just_location);
watch_command_1 (arg, accessflag, from_tty, just_location, 0);
}
static void
@ -8418,9 +8459,9 @@ watch_command (char *arg, int from_tty)
}
void
rwatch_command_wrapper (char *arg, int from_tty)
rwatch_command_wrapper (char *arg, int from_tty, int internal)
{
watch_command_1 (arg, hw_read, from_tty, 0);
watch_command_1 (arg, hw_read, from_tty, 0, internal);
}
static void
@ -8430,9 +8471,9 @@ rwatch_command (char *arg, int from_tty)
}
void
awatch_command_wrapper (char *arg, int from_tty)
awatch_command_wrapper (char *arg, int from_tty, int internal)
{
watch_command_1 (arg, hw_access, from_tty, 0);
watch_command_1 (arg, hw_access, from_tty, 0, internal);
}
static void
@ -8790,7 +8831,8 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
0,
AUTO_BOOLEAN_TRUE /* pending */,
&gnu_v3_exception_catchpoint_ops, from_tty,
1 /* enabled */);
1 /* enabled */,
0 /* internal */);
return 1;
}
@ -11010,7 +11052,8 @@ trace_command (char *arg, int from_tty)
pending_break_support,
NULL,
from_tty,
1 /* enabled */))
1 /* enabled */,
0 /* internal */))
set_tracepoint_count (breakpoint_count);
}
@ -11026,7 +11069,8 @@ ftrace_command (char *arg, int from_tty)
pending_break_support,
NULL,
from_tty,
1 /* enabled */))
1 /* enabled */,
0 /* internal */))
set_tracepoint_count (breakpoint_count);
}
@ -11044,7 +11088,8 @@ strace_command (char *arg, int from_tty)
pending_break_support,
NULL,
from_tty,
1 /* enabled */))
1 /* enabled */,
0 /* internal */))
set_tracepoint_count (breakpoint_count);
}
@ -11106,7 +11151,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
pending_break_support,
NULL,
0 /* from_tty */,
utp->enabled /* enabled */))
utp->enabled /* enabled */,
0 /* internal */))
return NULL;
set_tracepoint_count (breakpoint_count);
@ -11372,7 +11418,7 @@ save_breakpoints (char *filename, int from_tty,
ALL_BREAKPOINTS (tp)
{
/* Skip internal and momentary breakpoints. */
if (!user_settable_breakpoint (tp))
if (!user_settable_breakpoint (tp) || tp->number < 0)
continue;
/* If we have a filter, only save the breakpoints it accepts. */
@ -11410,7 +11456,7 @@ save_breakpoints (char *filename, int from_tty,
ALL_BREAKPOINTS (tp)
{
/* Skip internal and momentary breakpoints. */
if (!user_settable_breakpoint (tp))
if (!user_settable_breakpoint (tp) || tp->number < 0)
continue;
/* If we have a filter, only save the breakpoints it accepts. */
@ -11627,6 +11673,21 @@ save_command (char *arg, int from_tty)
help_list (save_cmdlist, "save ", -1, gdb_stdout);
}
struct breakpoint *
iterate_over_breakpoints (int (*callback) (struct breakpoint *, void *),
void *data)
{
struct breakpoint *b, *temp;
ALL_BREAKPOINTS_SAFE (b, temp)
{
if ((*callback) (b, data))
return b;
}
return NULL;
}
void
_initialize_breakpoint (void)
{

View File

@ -24,6 +24,11 @@
#include "value.h"
#include "vec.h"
#if HAVE_PYTHON
#include "python/python.h"
#include "python/python-internal.h"
#endif
struct value;
struct block;
@ -557,7 +562,14 @@ struct breakpoint
breakpoints, we will use this index to try to find the same
marker again. */
int static_trace_marker_id_idx;
};
/* With a Python scripting enabled GDB, store a reference to the
Python object that has been associated with this breakpoint.
This is always NULL for a GDB that is not script enabled. It
can sometimes be NULL for enabled GDBs as not all breakpoint
types are tracked by the Python scripting API. */
PyObject *py_bp_object;
};
typedef struct breakpoint *breakpoint_p;
DEF_VEC_P(breakpoint_p);
@ -855,9 +867,9 @@ extern void break_command (char *, int);
extern void hbreak_command_wrapper (char *, int);
extern void thbreak_command_wrapper (char *, int);
extern void rbreak_command_wrapper (char *, int);
extern void watch_command_wrapper (char *, int);
extern void awatch_command_wrapper (char *, int);
extern void rwatch_command_wrapper (char *, int);
extern void watch_command_wrapper (char *, int, int);
extern void awatch_command_wrapper (char *, int, int);
extern void rwatch_command_wrapper (char *, int, int);
extern void tbreak_command (char *, int);
extern int create_breakpoint (struct gdbarch *gdbarch, char *arg,
@ -868,7 +880,8 @@ extern int create_breakpoint (struct gdbarch *gdbarch, char *arg,
enum auto_boolean pending_break_support,
struct breakpoint_ops *ops,
int from_tty,
int enabled);
int enabled,
int internal);
extern void insert_breakpoints (void);
@ -1101,4 +1114,15 @@ extern void check_tracepoint_command (char *line, void *closure);
extern void start_rbreak_breakpoints (void);
extern void end_rbreak_breakpoints (void);
/* Breakpoint iterator function.
Calls a callback function once for each breakpoint, so long as the
callback function returns false. If the callback function returns
true, the iteration will end and the current breakpoint will be
returned. This can be useful for implementing a search for a
breakpoint with arbitrary attributes, or for applying an operation
to every breakpoint. */
extern struct breakpoint *iterate_over_breakpoints (int (*) (struct breakpoint *,
void *), void *);
#endif /* !defined (BREAKPOINT_H) */

View File

@ -1240,4 +1240,8 @@ void dummy_obstack_deallocate (void *object, void *data);
extern void initialize_progspace (void);
extern void initialize_inferiors (void);
#ifndef HAVE_PYTHON
typedef int PyObject;
#endif
#endif /* #ifndef DEFS_H */

View File

@ -1,3 +1,8 @@
2010-11-11 Phil Muldoon <pmuldoon@redhat.com>
* gdb.texinfo (Breakpoints In Python): Document "internal"
parameter, and visible attribute.
2010-11-05 Doug Evans <dje@google.com>
* gdb.texinfo (Source Path): Document "set directories".

View File

@ -22823,7 +22823,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{[}internal@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
@ -22831,10 +22831,14 @@ 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{internal} argument
allows the breakpoint to become invisible to the user. The breakpoint
will neither be reported when created, nor will it be listed in the
output from @code{info breakpoints} (but will be listed with the
@code{maint info breakpoints} command). 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.
@code{BP_WATCHPOINT}. If a watchpoint class is not provided, it is
assumed to be a @var{WP_WRITE} class.
@end defmethod
The available watchpoint types represented by constants are defined in the
@ -22909,6 +22913,12 @@ determine the actual breakpoint type or use-case. This attribute is not
writable.
@end defivar
@defivar Breakpoint visible
This attribute tells whether the breakpoint is visible to the user
when set, or when the @samp{info breakpoints} command is run. This
attribute is not writable.
@end defivar
The available types are represented by constants defined in the @code{gdb}
module:

View File

@ -169,7 +169,7 @@ mi_cmd_break_insert (char *command, char **argv, int argc)
temp_p, type_wanted,
ignore_count,
pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
NULL, 0, enabled);
NULL, 0, enabled, 0);
do_cleanups (back_to);
}
@ -259,13 +259,13 @@ mi_cmd_break_watch (char *command, char **argv, int argc)
switch (type)
{
case REG_WP:
watch_command_wrapper (expr, FROM_TTY);
watch_command_wrapper (expr, FROM_TTY, 0);
break;
case READ_WP:
rwatch_command_wrapper (expr, FROM_TTY);
rwatch_command_wrapper (expr, FROM_TTY, 0);
break;
case ACCESS_WP:
awatch_command_wrapper (expr, FROM_TTY);
awatch_command_wrapper (expr, FROM_TTY, 0);
break;
default:
error (_("mi_cmd_break_watch: Unknown watchpoint type."));

View File

@ -34,17 +34,6 @@ 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;
@ -68,7 +57,7 @@ struct breakpoint_object
exception if it is invalid. */
#define BPPY_REQUIRE_VALID(Breakpoint) \
do { \
if (! bpnum_is_valid ((Breakpoint)->number)) \
if ((Breakpoint)->bp == NULL) \
return PyErr_Format (PyExc_RuntimeError, _("Breakpoint %d is invalid."), \
(Breakpoint)->number); \
} while (0)
@ -77,7 +66,7 @@ struct breakpoint_object
exception if it is invalid. This macro is for use in setter functions. */
#define BPPY_SET_REQUIRE_VALID(Breakpoint) \
do { \
if (! bpnum_is_valid ((Breakpoint)->number)) \
if ((Breakpoint)->bp == NULL) \
{ \
PyErr_Format (PyExc_RuntimeError, _("Breakpoint %d is invalid."), \
(Breakpoint)->number); \
@ -115,18 +104,6 @@ static struct pybp_code pybp_watch_types[] =
{NULL} /* Sentinel. */
};
/* Evaluate to true if the breakpoint NUM is valid, false otherwise. */
static int
bpnum_is_valid (int num)
{
if (num >=0
&& num < bppy_slots
&& bppy_breakpoints[num] != NULL)
return 1;
return 0;
}
/* Python function which checks the validity of a breakpoint object. */
static PyObject *
bppy_is_valid (PyObject *self, PyObject *args)
@ -503,6 +480,21 @@ bppy_get_type (PyObject *self, void *closure)
return PyInt_FromLong (self_bp->bp->type);
}
/* Python function to get the visibility of the breakpoint. */
static PyObject *
bppy_get_visibility (PyObject *self, void *closure)
{
breakpoint_object *self_bp = (breakpoint_object *) self;
BPPY_REQUIRE_VALID (self_bp);
if (self_bp->bp->number < 0)
Py_RETURN_FALSE;
Py_RETURN_TRUE;
}
/* Python function to get the breakpoint's number. */
static PyObject *
bppy_get_number (PyObject *self, void *closure)
@ -569,16 +561,25 @@ static PyObject *
bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
{
PyObject *result;
static char *keywords[] = { "spec", "type", "wp_class", NULL };
static char *keywords[] = { "spec", "type", "wp_class", "internal", NULL };
char *spec;
int type = bp_breakpoint;
int access_type = hw_write;
PyObject *internal = NULL;
int internal_bp = 0;
volatile struct gdb_exception except;
if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|ii", keywords,
&spec, &type, &access_type))
if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiO", keywords,
&spec, &type, &access_type, &internal))
return NULL;
if (internal)
{
internal_bp = PyObject_IsTrue (internal);
if (internal_bp == -1)
return NULL;
}
result = subtype->tp_alloc (subtype, 0);
if (! result)
return NULL;
@ -598,17 +599,17 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
0, bp_breakpoint,
0,
AUTO_BOOLEAN_TRUE,
NULL, 0, 1);
NULL, 0, 1, internal_bp);
break;
}
case bp_watchpoint:
{
if (access_type == hw_write)
watch_command_wrapper (spec, 0);
watch_command_wrapper (spec, 0, internal_bp);
else if (access_type == hw_access)
awatch_command_wrapper (spec, 0);
awatch_command_wrapper (spec, 0, internal_bp);
else if (access_type == hw_read)
rwatch_command_wrapper (spec, 0);
rwatch_command_wrapper (spec, 0, internal_bp);
else
error(_("Cannot understand watchpoint access type."));
break;
@ -631,31 +632,50 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
static int
build_bp_list (struct breakpoint *b, void *arg)
{
PyObject *list = arg;
PyObject *bp = b->py_bp_object;
int iserr = 0;
/* Not all breakpoints will have a companion Python object.
Only breakpoints that were created via bppy_new, or
breakpoints that were created externally and are tracked by
the Python Scripting API. */
if (bp)
iserr = PyList_Append (list, bp);
if (iserr == -1)
return 1;
return 0;
}
/* Static function to return a tuple holding all breakpoints. */
PyObject *
gdbpy_breakpoints (PyObject *self, PyObject *args)
{
PyObject *result;
PyObject *list;
if (bppy_live == 0)
Py_RETURN_NONE;
result = PyTuple_New (bppy_live);
if (result)
{
int i, out = 0;
list = PyList_New (0);
if (!list)
return NULL;
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;
}
/* If iteratre_over_breakpoints returns non NULL it signals an error
condition. In that case abandon building the list and return
NULL. */
if (iterate_over_breakpoints (build_bp_list, list) != NULL)
{
Py_DECREF (list);
return NULL;
}
return result;
return PyList_AsTuple (list);
}
@ -671,13 +691,13 @@ gdbpy_breakpoint_created (int num)
struct breakpoint *bp = NULL;
PyGILState_STATE state;
if (num < 0)
return;
bp = get_breakpoint (num);
if (! bp)
return;
if (num < 0 && bppy_pending_object == NULL)
return;
if (bp->type != bp_breakpoint
&& bp->type != bp_watchpoint
&& bp->type != bp_hardware_watchpoint
@ -685,21 +705,6 @@ 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)
@ -713,12 +718,16 @@ gdbpy_breakpoint_created (int num)
{
newbp->number = num;
newbp->bp = bp;
bppy_breakpoints[num] = newbp;
newbp->bp->py_bp_object = (PyObject *) newbp;
Py_INCREF (newbp);
++bppy_live;
}
else
{
PyErr_SetString (PyExc_RuntimeError,
_("Error while creating breakpoint from GDB."));
gdbpy_print_stack ();
}
/* Just ignore errors here. */
PyErr_Clear ();
PyGILState_Release (state);
}
@ -729,14 +738,20 @@ static void
gdbpy_breakpoint_deleted (int num)
{
PyGILState_STATE state;
struct breakpoint *bp = NULL;
breakpoint_object *bp_obj;
state = PyGILState_Ensure ();
if (bpnum_is_valid (num))
bp = get_breakpoint (num);
if (! bp)
return;
bp_obj = ((breakpoint_object *) bp->py_bp_object);
if (bp_obj)
{
bppy_breakpoints[num]->bp = NULL;
Py_DECREF (bppy_breakpoints[num]);
bppy_breakpoints[num] = NULL;
bp_obj->bp = NULL;
--bppy_live;
Py_DECREF (bp_obj);
}
PyGILState_Release (state);
}
@ -819,6 +834,8 @@ 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,
"Whether the breakpoint is visible to the user."},
{ NULL } /* Sentinel. */
};

View File

@ -1895,7 +1895,8 @@ spu_catch_start (struct objfile *objfile)
bp_breakpoint /* type_wanted */,
0 /* ignore_count */,
AUTO_BOOLEAN_FALSE /* pending_break_support */,
NULL /* ops */, 0 /* from_tty */, 1 /* enabled */);
NULL /* ops */, 0 /* from_tty */, 1 /* enabled */,
0 /* internal */););
}

View File

@ -1,3 +1,8 @@
2010-11-11 Phil Muldoon <pmuldoon@redhat.com>
* gdb.python/py-breakpoint.exp: Add internal watchpoint and
breakpoint tests.
2010-11-09 Pedro Alves <pedro@codesourcery.com>
* gdb.base/watchpoint.exp: Test "watch -location" with an

View File

@ -117,6 +117,33 @@ 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\", internal=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" "True" "Check breakpoint visibility"
gdb_test "info breakpoints" "py-breakpoint\.c:$ibp_location.*" "Check info breakpoints shows visible breakpoints"
delete_breakpoints
gdb_py_test_silent_cmd "python ibp = gdb.Breakpoint(\"$ibp_location\", internal=True)" "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" "False" "Check breakpoint visibility"
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"
# Watchpoints
# Start with a fresh gdb.
clean_restart ${testfile}
@ -134,5 +161,17 @@ 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 "continue" ".*\[Ww\]atchpoint.*result.*Old value = 0.*New value = 25.*main.*" "Test watchpoint write"
# Internal breakpoints.
# Start with a fresh gdb.
clean_restart ${testfile}
if ![runto_main] then {
fail "Cannot run to main."
return 0
}
delete_breakpoints
gdb_py_test_silent_cmd "python wp1 = gdb.Breakpoint (\"result\", type=gdb.BP_WATCHPOINT, wp_class=gdb.WP_WRITE, internal=True )" "Set watchpoint" 0
gdb_test "info breakpoints" "No breakpoints or watchpoints.*" "Check info breakpoints does not show invisible breakpoints"
gdb_test "maint info breakpoints" ".*hw watchpoint.*result.*" "Check maint info breakpoints shows invisible breakpoints"
gdb_test "continue" ".*\[Ww\]atchpoint.*result.*Old value = 0.*New value = 25.*" "Test watchpoint write"

View File

@ -39,8 +39,6 @@
#if HAVE_PYTHON
#include "python/python.h"
#include "python/python-internal.h"
#else
typedef int PyObject;
#endif
/* Non-zero if we want to see trace of varobj level stuff. */