2012-01-16 Sergio Durigan Junior <sergiodj@redhat.com>

* breakpoint.c (create_sals_from_address_default): New function.
(create_breakpoints_sal_default): Likewise.
(decode_linespec_default): Likewise.
(is_marker_spec): Removed.
(strace_marker_p): New function.
(init_breakpoint_sal): Using `strace_marker_p' instead of
`is_marker_spec'.
(create_breakpoint): Call method `create_sals_from_address' from
breakpoint_ops, replacing code that created SALs conditionally
on the type of the breakpoint.  Call method `create_breakpoints_sal',
replacing code that created breakpoints conditionally on the type
wanted.
(base_breakpoint_create_sals_from_address): New function.
(base_breakpoint_create_breakpoints_sal): Likewise.
(base_breakpoint_decode_linespec): Likewise.
(base_breakpoint_ops): Add methods
`base_breakpoint_create_sals_from_address',
`base_breakpoint_create_breakpoints_sal' and
`base_breakpoint_decode_linespec'.
(bkpt_create_sals_from_address): New function.
(bkpt_create_breakpoints_sal): Likewise.
(bkpt_decode_linespec): Likewise.
(tracepoint_create_sals_from_address): Likewise.
(tracepoint_create_breakpoints_sal): Likewise.
(tracepoint_decode_linespec): Likewise.
(strace_marker_create_sals_from_address): Likewise.
(strace_marker_create_breakpoints_sal): Likewise.
(strace_marker_decode_linespec): Likewise.
(strace_marker_breakpoint_ops): New variable.
(addr_string_to_sals): Remove `marker_spec'.  Call method
`decode_linespec' from breakpoint_ops, replacing code that decoded
an address string into a SAL.  Use `strace_marker_p' instead of
`marker_spec'.
(strace_command): Decide whether we are dealing with a static
tracepoint with marker or not.  Use the appropriate breakpoint_ops.
(initialize_breakpoint_ops): Initialize new fields of breakpoint_ops.
* breakpoint.h (linespec_result, linespec_sals): New forward
declarations.
(breakpoint_ops) <create_sals_from_address>,
<create_breakpoints_sal>, <decode_linespec>: New methods.
This commit is contained in:
Sergio Durigan Junior 2012-01-16 17:44:36 +00:00
parent abcc497831
commit 983af33b26
3 changed files with 411 additions and 120 deletions

View File

@ -1,3 +1,46 @@
2012-01-16 Sergio Durigan Junior <sergiodj@redhat.com>
* breakpoint.c (create_sals_from_address_default): New function.
(create_breakpoints_sal_default): Likewise.
(decode_linespec_default): Likewise.
(is_marker_spec): Removed.
(strace_marker_p): New function.
(init_breakpoint_sal): Using `strace_marker_p' instead of
`is_marker_spec'.
(create_breakpoint): Call method `create_sals_from_address' from
breakpoint_ops, replacing code that created SALs conditionally
on the type of the breakpoint. Call method `create_breakpoints_sal',
replacing code that created breakpoints conditionally on the type
wanted.
(base_breakpoint_create_sals_from_address): New function.
(base_breakpoint_create_breakpoints_sal): Likewise.
(base_breakpoint_decode_linespec): Likewise.
(base_breakpoint_ops): Add methods
`base_breakpoint_create_sals_from_address',
`base_breakpoint_create_breakpoints_sal' and
`base_breakpoint_decode_linespec'.
(bkpt_create_sals_from_address): New function.
(bkpt_create_breakpoints_sal): Likewise.
(bkpt_decode_linespec): Likewise.
(tracepoint_create_sals_from_address): Likewise.
(tracepoint_create_breakpoints_sal): Likewise.
(tracepoint_decode_linespec): Likewise.
(strace_marker_create_sals_from_address): Likewise.
(strace_marker_create_breakpoints_sal): Likewise.
(strace_marker_decode_linespec): Likewise.
(strace_marker_breakpoint_ops): New variable.
(addr_string_to_sals): Remove `marker_spec'. Call method
`decode_linespec' from breakpoint_ops, replacing code that decoded
an address string into a SAL. Use `strace_marker_p' instead of
`marker_spec'.
(strace_command): Decide whether we are dealing with a static
tracepoint with marker or not. Use the appropriate breakpoint_ops.
(initialize_breakpoint_ops): Initialize new fields of breakpoint_ops.
* breakpoint.h (linespec_result, linespec_sals): New forward
declarations.
(breakpoint_ops) <create_sals_from_address>,
<create_breakpoints_sal>, <decode_linespec>: New methods.
2012-01-14 Doug Evans <dje@google.com>
* NEWS: Update text for "maint set python print-stack".

View File

@ -96,6 +96,23 @@ static int breakpoint_re_set_one (void *);
static void breakpoint_re_set_default (struct breakpoint *);
static void create_sals_from_address_default (char **,
struct linespec_result *,
enum bptype, char *,
char **);
static void create_breakpoints_sal_default (struct gdbarch *,
struct linespec_result *,
struct linespec_sals *,
char *, enum bptype,
enum bpdisp, int, int,
int,
const struct breakpoint_ops *,
int, int, int);
static void decode_linespec_default (struct breakpoint *, char **,
struct symtabs_and_lines *);
static void clear_command (char *, int);
static void catch_command (char *, int);
@ -237,10 +254,10 @@ static void trace_pass_command (char *, int);
static int is_masked_watchpoint (const struct breakpoint *b);
/* Assuming we're creating a static tracepoint, does S look like a
static tracepoint marker spec ("-m MARKER_ID")? */
#define is_marker_spec(s) \
(s != NULL && strncmp (s, "-m", 2) == 0 && ((s)[2] == ' ' || (s)[2] == '\t'))
/* Return 1 if B refers to a static tracepoint set by marker ("-m"), zero
otherwise. */
static int strace_marker_p (struct breakpoint *b);
/* The abstract base class all breakpoint_ops structures inherit
from. */
@ -7298,7 +7315,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
struct tracepoint *t = (struct tracepoint *) b;
struct static_tracepoint_marker marker;
if (is_marker_spec (addr_string))
if (strace_marker_p (b))
{
/* We already know the marker exists, otherwise, we
wouldn't see a sal for it. */
@ -7720,32 +7737,19 @@ create_breakpoint (struct gdbarch *gdbarch,
init_linespec_result (&canonical);
if (type_wanted == bp_static_tracepoint && is_marker_spec (arg))
{
int i;
struct linespec_sals lsal;
lsal.sals = decode_static_tracepoint_spec (&arg);
copy_arg = savestring (addr_start, arg - addr_start);
canonical.addr_string = xstrdup (copy_arg);
lsal.canonical = xstrdup (copy_arg);
VEC_safe_push (linespec_sals, canonical.sals, &lsal);
goto done;
}
TRY_CATCH (e, RETURN_MASK_ALL)
{
parse_breakpoint_sals (&arg, &canonical);
ops->create_sals_from_address (&arg, &canonical, type_wanted,
addr_start, &copy_arg);
}
/* If caller is interested in rc value from parse, set value. */
switch (e.reason)
{
case RETURN_QUIT:
throw_exception (e);
case GDB_NO_ERROR:
if (VEC_empty (linespec_sals, canonical.sals))
return 0;
break;
case RETURN_ERROR:
switch (e.error)
{
@ -7787,12 +7791,9 @@ create_breakpoint (struct gdbarch *gdbarch,
}
break;
default:
if (VEC_empty (linespec_sals, canonical.sals))
return 0;
throw_exception (e);
}
done:
/* Create a chain of things that always need to be cleaned up. */
old_chain = make_cleanup_destroy_linespec_result (&canonical);
@ -7855,57 +7856,11 @@ create_breakpoint (struct gdbarch *gdbarch,
}
}
/* If the user is creating a static tracepoint by marker id
(strace -m MARKER_ID), then store the sals index, so that
breakpoint_re_set can try to match up which of the newly
found markers corresponds to this one, and, don't try to
expand multiple locations for each sal, given than SALS
already should contain all sals for MARKER_ID. */
if (type_wanted == bp_static_tracepoint
&& is_marker_spec (copy_arg))
{
int i;
for (i = 0; i < lsal->sals.nelts; ++i)
{
struct symtabs_and_lines expanded;
struct tracepoint *tp;
struct cleanup *old_chain;
char *addr_string;
expanded.nelts = 1;
expanded.sals = &lsal->sals.sals[i];
addr_string = xstrdup (canonical.addr_string);
old_chain = make_cleanup (xfree, addr_string);
tp = XCNEW (struct tracepoint);
init_breakpoint_sal (&tp->base, gdbarch, expanded,
addr_string, NULL,
ops->create_breakpoints_sal (gdbarch, &canonical, lsal,
cond_string, type_wanted,
tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops,
from_tty, enabled, internal,
canonical.special_display);
/* Given that its possible to have multiple markers with
the same string id, if the user is creating a static
tracepoint by marker id ("strace -m MARKER_ID"), then
store the sals index, so that breakpoint_re_set can
try to match up which of the newly found markers
corresponds to this one */
tp->static_trace_marker_id_idx = i;
install_breakpoint (internal, &tp->base, 0);
discard_cleanups (old_chain);
}
}
else
create_breakpoints_sal (gdbarch, &canonical, cond_string,
type_wanted,
tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops, from_tty,
enabled, internal);
from_tty, enabled, internal);
}
else
{
@ -10910,6 +10865,39 @@ base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
internal_error_pure_virtual_called ();
}
static void
base_breakpoint_create_sals_from_address (char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start,
char **copy_arg)
{
internal_error_pure_virtual_called ();
}
static void
base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
struct linespec_result *c,
struct linespec_sals *lsal,
char *cond_string,
enum bptype type_wanted,
enum bpdisp disposition,
int thread,
int task, int ignore_count,
const struct breakpoint_ops *o,
int from_tty, int enabled,
int internal)
{
internal_error_pure_virtual_called ();
}
static void
base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
struct symtabs_and_lines *sals)
{
internal_error_pure_virtual_called ();
}
static struct breakpoint_ops base_breakpoint_ops =
{
base_breakpoint_dtor,
@ -10925,7 +10913,10 @@ static struct breakpoint_ops base_breakpoint_ops =
NULL,
base_breakpoint_print_one_detail,
base_breakpoint_print_mention,
base_breakpoint_print_recreate
base_breakpoint_print_recreate,
base_breakpoint_create_sals_from_address,
base_breakpoint_create_breakpoints_sal,
base_breakpoint_decode_linespec,
};
/* Default breakpoint_ops methods. */
@ -11071,6 +11062,43 @@ bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
print_recreate_thread (tp, fp);
}
static void
bkpt_create_sals_from_address (char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
{
create_sals_from_address_default (arg, canonical, type_wanted,
addr_start, copy_arg);
}
static void
bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
struct linespec_result *canonical,
struct linespec_sals *lsal,
char *cond_string,
enum bptype type_wanted,
enum bpdisp disposition,
int thread,
int task, int ignore_count,
const struct breakpoint_ops *ops,
int from_tty, int enabled,
int internal)
{
create_breakpoints_sal_default (gdbarch, canonical, lsal,
cond_string, type_wanted,
disposition, thread, task,
ignore_count, ops, from_tty,
enabled, internal);
}
static void
bkpt_decode_linespec (struct breakpoint *b, char **s,
struct symtabs_and_lines *sals)
{
decode_linespec_default (b, s, sals);
}
/* Virtual table for internal breakpoints. */
static void
@ -11297,8 +11325,145 @@ tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp)
fprintf_unfiltered (fp, " passcount %d\n", tp->pass_count);
}
static void
tracepoint_create_sals_from_address (char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
{
create_sals_from_address_default (arg, canonical, type_wanted,
addr_start, copy_arg);
}
static void
tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
struct linespec_result *canonical,
struct linespec_sals *lsal,
char *cond_string,
enum bptype type_wanted,
enum bpdisp disposition,
int thread,
int task, int ignore_count,
const struct breakpoint_ops *ops,
int from_tty, int enabled,
int internal)
{
create_breakpoints_sal_default (gdbarch, canonical, lsal,
cond_string, type_wanted,
disposition, thread, task,
ignore_count, ops, from_tty,
enabled, internal);
}
static void
tracepoint_decode_linespec (struct breakpoint *b, char **s,
struct symtabs_and_lines *sals)
{
decode_linespec_default (b, s, sals);
}
struct breakpoint_ops tracepoint_breakpoint_ops;
/* The breakpoint_ops structure to be used on static tracepoints with
markers (`-m'). */
static void
strace_marker_create_sals_from_address (char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
{
struct linespec_sals lsal;
lsal.sals = decode_static_tracepoint_spec (arg);
*copy_arg = savestring (addr_start, *arg - addr_start);
canonical->addr_string = xstrdup (*copy_arg);
lsal.canonical = xstrdup (*copy_arg);
VEC_safe_push (linespec_sals, canonical->sals, &lsal);
}
static void
strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
struct linespec_result *canonical,
struct linespec_sals *lsal,
char *cond_string,
enum bptype type_wanted,
enum bpdisp disposition,
int thread,
int task, int ignore_count,
const struct breakpoint_ops *ops,
int from_tty, int enabled,
int internal)
{
int i;
/* If the user is creating a static tracepoint by marker id
(strace -m MARKER_ID), then store the sals index, so that
breakpoint_re_set can try to match up which of the newly
found markers corresponds to this one, and, don't try to
expand multiple locations for each sal, given than SALS
already should contain all sals for MARKER_ID. */
for (i = 0; i < lsal->sals.nelts; ++i)
{
struct symtabs_and_lines expanded;
struct tracepoint *tp;
struct cleanup *old_chain;
char *addr_string;
expanded.nelts = 1;
expanded.sals = &lsal->sals.sals[i];
addr_string = xstrdup (canonical->addr_string);
old_chain = make_cleanup (xfree, addr_string);
tp = XCNEW (struct tracepoint);
init_breakpoint_sal (&tp->base, gdbarch, expanded,
addr_string, NULL,
cond_string, type_wanted, disposition,
thread, task, ignore_count, ops,
from_tty, enabled, internal,
canonical->special_display);
/* Given that its possible to have multiple markers with
the same string id, if the user is creating a static
tracepoint by marker id ("strace -m MARKER_ID"), then
store the sals index, so that breakpoint_re_set can
try to match up which of the newly found markers
corresponds to this one */
tp->static_trace_marker_id_idx = i;
install_breakpoint (internal, &tp->base, 0);
discard_cleanups (old_chain);
}
}
static void
strace_marker_decode_linespec (struct breakpoint *b, char **s,
struct symtabs_and_lines *sals)
{
struct tracepoint *tp = (struct tracepoint *) b;
*sals = decode_static_tracepoint_spec (s);
if (sals->nelts > tp->static_trace_marker_id_idx)
{
sals->sals[0] = sals->sals[tp->static_trace_marker_id_idx];
sals->nelts = 1;
}
else
error (_("marker %s not found"), tp->static_trace_marker_id);
}
static struct breakpoint_ops strace_marker_breakpoint_ops;
static int
strace_marker_p (struct breakpoint *b)
{
return b->ops == &strace_marker_breakpoint_ops;
}
/* Delete a breakpoint and clean up all traces of it in the data
structures. */
@ -11833,54 +11998,15 @@ static struct symtabs_and_lines
addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
{
char *s;
int marker_spec;
struct symtabs_and_lines sals = {0};
volatile struct gdb_exception e;
gdb_assert (b->ops != NULL);
s = addr_string;
marker_spec = b->type == bp_static_tracepoint && is_marker_spec (s);
TRY_CATCH (e, RETURN_MASK_ERROR)
{
if (marker_spec)
{
struct tracepoint *tp = (struct tracepoint *) b;
sals = decode_static_tracepoint_spec (&s);
if (sals.nelts > tp->static_trace_marker_id_idx)
{
sals.sals[0] = sals.sals[tp->static_trace_marker_id_idx];
sals.nelts = 1;
}
else
error (_("marker %s not found"), tp->static_trace_marker_id);
}
else
{
struct linespec_result canonical;
init_linespec_result (&canonical);
decode_line_full (&s, DECODE_LINE_FUNFIRSTLINE,
(struct symtab *) NULL, 0,
&canonical, multiple_symbols_all,
b->filter);
/* We should get 0 or 1 resulting SALs. */
gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
if (VEC_length (linespec_sals, canonical.sals) > 0)
{
struct linespec_sals *lsal;
lsal = VEC_index (linespec_sals, canonical.sals, 0);
sals = lsal->sals;
/* Arrange it so the destructor does not free the
contents. */
lsal->sals.sals = NULL;
}
destroy_linespec_result (&canonical);
}
b->ops->decode_linespec (b, &s, &sals);
}
if (e.reason < 0)
{
@ -11933,7 +12059,7 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
b->condition_not_parsed = 0;
}
if (b->type == bp_static_tracepoint && !marker_spec)
if (b->type == bp_static_tracepoint && !strace_marker_p (b))
sals.sals[0] = update_static_tracepoint (b, sals.sals[0]);
*found = 1;
@ -11976,6 +12102,73 @@ breakpoint_re_set_default (struct breakpoint *b)
update_breakpoint_locations (b, expanded, expanded_end);
}
/* Default method for creating SALs from an address string. It basically
calls parse_breakpoint_sals. Return 1 for success, zero for failure. */
static void
create_sals_from_address_default (char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
{
parse_breakpoint_sals (arg, canonical);
}
/* Call create_breakpoints_sal for the given arguments. This is the default
function for the `create_breakpoints_sal' method of
breakpoint_ops. */
static void
create_breakpoints_sal_default (struct gdbarch *gdbarch,
struct linespec_result *canonical,
struct linespec_sals *lsal,
char *cond_string,
enum bptype type_wanted,
enum bpdisp disposition,
int thread,
int task, int ignore_count,
const struct breakpoint_ops *ops,
int from_tty, int enabled,
int internal)
{
create_breakpoints_sal (gdbarch, canonical, cond_string,
type_wanted, disposition,
thread, task, ignore_count, ops, from_tty,
enabled, internal);
}
/* Decode the line represented by S by calling decode_line_full. This is the
default function for the `decode_linespec' method of breakpoint_ops. */
static void
decode_linespec_default (struct breakpoint *b, char **s,
struct symtabs_and_lines *sals)
{
struct linespec_result canonical;
init_linespec_result (&canonical);
decode_line_full (s, DECODE_LINE_FUNFIRSTLINE,
(struct symtab *) NULL, 0,
&canonical, multiple_symbols_all,
b->filter);
/* We should get 0 or 1 resulting SALs. */
gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
if (VEC_length (linespec_sals, canonical.sals) > 0)
{
struct linespec_sals *lsal;
lsal = VEC_index (linespec_sals, canonical.sals, 0);
*sals = lsal->sals;
/* Arrange it so the destructor does not free the
contents. */
lsal->sals.sals = NULL;
}
destroy_linespec_result (&canonical);
}
/* Prepare the global context for a re-set of breakpoint B. */
static struct cleanup *
@ -12794,6 +12987,15 @@ ftrace_command (char *arg, int from_tty)
void
strace_command (char *arg, int from_tty)
{
struct breakpoint_ops *ops;
/* Decide if we are dealing with a static tracepoint marker (`-m'),
or with a normal static tracepoint. */
if (arg && strncmp (arg, "-m", 2) == 0 && isspace (arg[2]))
ops = &strace_marker_breakpoint_ops;
else
ops = &tracepoint_breakpoint_ops;
if (create_breakpoint (get_current_arch (),
arg,
NULL, 0, 1 /* parse arg */,
@ -12801,7 +13003,7 @@ strace_command (char *arg, int from_tty)
bp_static_tracepoint /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
&tracepoint_breakpoint_ops,
ops,
from_tty,
1 /* enabled */,
0 /* internal */))
@ -13446,6 +13648,9 @@ initialize_breakpoint_ops (void)
ops->insert_location = bkpt_insert_location;
ops->remove_location = bkpt_remove_location;
ops->breakpoint_hit = bkpt_breakpoint_hit;
ops->create_sals_from_address = bkpt_create_sals_from_address;
ops->create_breakpoints_sal = bkpt_create_breakpoints_sal;
ops->decode_linespec = bkpt_decode_linespec;
/* The breakpoint_ops structure to be used in regular breakpoints. */
ops = &bkpt_breakpoint_ops;
@ -13526,6 +13731,16 @@ initialize_breakpoint_ops (void)
ops->print_one_detail = tracepoint_print_one_detail;
ops->print_mention = tracepoint_print_mention;
ops->print_recreate = tracepoint_print_recreate;
ops->create_sals_from_address = tracepoint_create_sals_from_address;
ops->create_breakpoints_sal = tracepoint_create_breakpoints_sal;
ops->decode_linespec = tracepoint_decode_linespec;
/* Static tracepoints with marker (`-m'). */
ops = &strace_marker_breakpoint_ops;
*ops = tracepoint_breakpoint_ops;
ops->create_sals_from_address = strace_marker_create_sals_from_address;
ops->create_breakpoints_sal = strace_marker_create_breakpoints_sal;
ops->decode_linespec = strace_marker_decode_linespec;
/* Fork catchpoints. */
ops = &catch_fork_breakpoint_ops;

View File

@ -30,6 +30,8 @@ struct get_number_or_range_state;
struct thread_info;
struct bpstats;
struct bp_location;
struct linespec_result;
struct linespec_sals;
/* This is the maximum number of bytes a breakpoint instruction can
take. Feel free to increase it. It's just used in a few places to
@ -482,6 +484,37 @@ struct breakpoint_ops
/* Print to FP the CLI command that recreates this breakpoint. */
void (*print_recreate) (struct breakpoint *, struct ui_file *fp);
/* Create SALs from address string, storing the result in linespec_result.
For an explanation about the arguments, see the function
`create_sals_from_address_default'.
This function is called inside `create_breakpoint'. */
void (*create_sals_from_address) (char **, struct linespec_result *,
enum bptype, char *, char **);
/* This method will be responsible for creating a breakpoint given its SALs.
Usually, it just calls `create_breakpoints_sal' (for ordinary
breakpoints). However, there may be some special cases where we might
need to do some tweaks, e.g., see
`strace_marker_create_breakpoints_sal'.
This function is called inside `create_breakpoint'. */
void (*create_breakpoints_sal) (struct gdbarch *,
struct linespec_result *,
struct linespec_sals *, char *,
enum bptype, enum bpdisp, int, int,
int, const struct breakpoint_ops *,
int, int, int);
/* Given the address string (second parameter), this method decodes it
and provides the SAL locations related to it. For ordinary breakpoints,
it calls `decode_line_full'.
This function is called inside `addr_string_to_sals'. */
void (*decode_linespec) (struct breakpoint *, char **,
struct symtabs_and_lines *);
};
/* Helper for breakpoint_ops->print_recreate implementations. Prints