This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA 2/5] Explicit linespecs - breakpoint API
- From: Keith Seitz <keiths at redhat dot com>
- To: "gdb-patches at sourceware dot org ml" <gdb-patches at sourceware dot org>
- Date: Thu, 26 Jul 2012 20:47:28 -0700
- Subject: [RFA 2/5] Explicit linespecs - breakpoint API
Hello,
This patch is fairly mechanical. It adds the new explicit_linespec *
parameter to create_breakpoint and several other breakpoint.c functions.
It does /not/ actually cause the explicit linespec to be used. That
interesting tidbit is in the next patch.
There is one little refactoring included in this patch, too. I've ripped
create_breakpoint into two parts, creating what I felt was a much more
readable logic, and removing the two separate cleanups into separate
functions. Maybe it's just me, but create_breakpoint was just *way* too
big. [Of course, create_breakpoint_1 is still too big...]
Questions/comments/concerns?
Keith
ChangeLog
2012-07-26 Keith Seitz <keiths@redhat.com>
* breakpoint.h (breakpoint_ops.create_sals_from_address):
Add explicit_linespec parameter.
(breakpoint_ops.decode_linespec): Likewise.
(create_breakpoint): Likewise.
* breakpoint.c (init_breakpoint_sal): Add
explicit_linespec parameter.
(create_breakpoint_sal): Pass canonical->explicit to
init_breakpoint_sal.
(parse_breakpoint_sals): Add explicit_linespec parameter.
(create_breakpoint_1): Move a bunch of code
from create_breakpoint to here.
(create_breakpoint): Move much of breakpoint creation into
create_breakpoint_1.
(dprintf_command): Pass NULL for explicit_linespec to
create_breakpoint.
(break_range_command): Likewise for parse_breakpoint_sals.
(handle_gnu_v3_exceptions): Likewise for create_breakpoint.
(base_breakpoint_create_sals_from_address): Add
explicit_linespec parameter.
(base_breakpoint_decode_linespec): Likewise.
(bkpt_create_sals_from_address): Add explicit_linespec parameter
and pass it to create_sals_from_address_default.
(bkpt_decode_linespec): Add explicit_linespec parameter and pass
it to decode_linespec_default.
(bkpt_probe_create_sals_from_address): Add explicit_linespec
parameter.
(bkpt_probe_decode_linespec): Likewise.
(tracepoint_create_sals_from_address): Add explicit_linespec
parameter and pass it to create_sals_from_address_default.
(tracepoint_decode_linespec): Likewise with linespec_default.
(tracepoint_probe_create_sals_from_address): Likewise
with bkpt_probe_create_sals_from_address.
(tracepoint_probe_decode_linespec): Likewise with
bkpt_probe_decode_linespec.
(strace_marker_create_sals_from_address): Add explicit_linespec
parameter.
(strace_marker_create_breakpoints_sal): Pass canonical->explicit
to init_breakpoint_sal.
(strace_marker_decode_linespec): Add explicit_linespec
parameter.
(addr_string_to_sals): Add explicit_linespec parameter and
pass it to ops->decode_linespec.
(breakpoint_re_set_default): Pass B->EXPLICIT to
addr_string_to_sals.
(create_sals_from_address_default): Add explicit_linespec
parameter and pass it to parse_breakpoint_sals.
(decode_linespec_default): Add explicit_linespec parameter.
(trace_command): Pass NULL for explicit_linespec to
create_breakpoint.
(ftrace_command): Likewise.
(strace_command): Likewise.
(create_tracepoint_from_upload): Likewise.
* linespec.h (struct explicit_linespec): New struct.
* mi/mi-cmd-break.c: Include linespec.h.
(mi_cmd_break_insert): Pass NULL as explicit linespec to
create_breakpoint.
* python/py-breakpoint.c (bppy_init): Likewise.
* python/py-finishbreakpoint.c (bpfinishpy_init): Likewise.
* spu-tdep.c (spu_catch_start): Pass NULL as explicit_linespec
to create_breakpoint.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 03719d4..35d55ba 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -104,7 +104,7 @@ static int breakpoint_re_set_one (void *);
static void breakpoint_re_set_default (struct breakpoint *);
-static void create_sals_from_address_default (char **,
+static void create_sals_from_address_default (explicit_linespec *, char **,
struct linespec_result *,
enum bptype, char *,
char **);
@@ -118,8 +118,8 @@ static void create_breakpoints_sal_default (struct gdbarch *,
const struct breakpoint_ops *,
int, int, int, unsigned);
-static void decode_linespec_default (struct breakpoint *, char **,
- struct symtabs_and_lines *);
+static void decode_linespec_default (struct breakpoint *, explicit_linespec *,
+ char **, struct symtabs_and_lines *);
static void clear_command (char *, int);
@@ -8866,12 +8866,13 @@ update_dprintf_commands (char *args, int from_tty,
}
/* Create a breakpoint with SAL as location. Use ADDR_STRING
- as textual description of the location, and COND_STRING
- as condition expression. */
+ as textual description of the location (or ELS as an explicit
+ description), and COND_STRING as condition expression. */
static void
init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
- struct symtabs_and_lines sals, char *addr_string,
+ struct symtabs_and_lines sals,
+ explicit_linespec *els, char *addr_string,
char *filter, char *cond_string,
char *extra_string,
enum bptype type, enum bpdisp disposition,
@@ -9013,7 +9014,8 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
static void
create_breakpoint_sal (struct gdbarch *gdbarch,
- struct symtabs_and_lines sals, char *addr_string,
+ struct symtabs_and_lines sals,
+ explicit_linespec *els, char *addr_string,
char *filter, char *cond_string,
char *extra_string,
enum bptype type, enum bpdisp disposition,
@@ -9038,7 +9040,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
old_chain = make_cleanup (xfree, b);
init_breakpoint_sal (b, gdbarch,
- sals, addr_string,
+ sals, NULL, addr_string,
filter, cond_string, extra_string,
type, disposition,
thread, task, ignore_count,
@@ -9092,7 +9094,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
make_cleanup (xfree, filter_string);
create_breakpoint_sal (gdbarch, lsal->sals,
- addr_string,
+ NULL, addr_string,
filter_string,
cond_string, extra_string,
type, disposition,
@@ -9112,7 +9114,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
the caller's responsibility to free them. */
static void
-parse_breakpoint_sals (char **address,
+parse_breakpoint_sals (explicit_linespec *els, char **address,
struct linespec_result *canonical)
{
char *addr_start = *address;
@@ -9366,118 +9368,101 @@ decode_static_tracepoint_spec (char **arg_p)
return sals;
}
-/* Set a breakpoint. This function is shared between CLI and MI
- functions for setting a breakpoint. This function has two major
- modes of operations, selected by the PARSE_CONDITION_AND_THREAD
- 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. 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. */
+/* The workhorse of create_breakpoint.
+ See the comments of create_breakpoint for parameter meanings. */
-int
-create_breakpoint (struct gdbarch *gdbarch,
- char *arg, char *cond_string,
- int thread, char *extra_string,
- int parse_condition_and_thread,
- int tempflag, enum bptype type_wanted,
- int ignore_count,
- enum auto_boolean pending_break_support,
- const struct breakpoint_ops *ops,
- int from_tty, int enabled, int internal,
- unsigned flags)
+static int
+create_breakpoint_1 (struct gdbarch *gdbarch,
+ struct linespec_result *canonical, char *arg,
+ char *cond_string, int thread, char *extra_string,
+ int parse_condition_and_thread,
+ int tempflag, enum bptype type_wanted, int ignore_count,
+ enum auto_boolean pending_break_support,
+ const struct breakpoint_ops *ops,
+ int from_tty, int enabled, int internal, int flags)
{
- volatile struct gdb_exception e;
- char *copy_arg = NULL;
- char *addr_start = arg;
- struct linespec_result canonical;
- struct cleanup *old_chain;
- struct cleanup *bkpt_chain = NULL;
+ struct cleanup *bkpt_chain;
int pending = 0;
- int task = 0;
int prev_bkpt_count = breakpoint_count;
+ int task = 0;
- gdb_assert (ops != NULL);
-
- init_linespec_result (&canonical);
+ /* Anything added to the cleanup chain is assumed to be part of a
+ breakpoint. If the breakpoint create succeeds then the memory is
+ not reclaimed. */
+ bkpt_chain = make_cleanup (null_cleanup, 0);
- TRY_CATCH (e, RETURN_MASK_ALL)
+ if (canonical->sals == NULL)
{
- ops->create_sals_from_address (&arg, &canonical, type_wanted,
- addr_start, ©_arg);
- }
+ struct linespec_sals lsal;
- /* If caller is interested in rc value from parse, set value. */
- switch (e.reason)
- {
- case GDB_NO_ERROR:
- if (VEC_empty (linespec_sals, canonical.sals))
+ /* If pending breakpoint support is auto query and the user
+ selects no, then simply return the error code. */
+ if (pending_break_support == AUTO_BOOLEAN_AUTO
+ && !nquery (_("Make %s pending on future shared library load? "),
+ bptype_string (type_wanted)))
return 0;
- break;
- case RETURN_ERROR:
- switch (e.error)
- {
- case NOT_FOUND_ERROR:
-
- /* If pending breakpoint support is turned off, throw
- error. */
- if (pending_break_support == AUTO_BOOLEAN_FALSE)
- throw_exception (e);
-
- exception_print (gdb_stderr, e);
-
- /* If pending breakpoint support is auto query and the user
- selects no, then simply return the error code. */
- if (pending_break_support == AUTO_BOOLEAN_AUTO
- && !nquery (_("Make %s pending on future shared library load? "),
- bptype_string (type_wanted)))
- return 0;
-
- /* At this point, either the user was queried about setting
- a pending breakpoint and selected yes, or pending
- breakpoint behavior is on and thus a pending breakpoint
- is defaulted on behalf of the user. */
- {
- struct linespec_sals lsal;
-
- copy_arg = xstrdup (addr_start);
- lsal.canonical = xstrdup (copy_arg);
- lsal.sals.nelts = 1;
- lsal.sals.sals = XNEW (struct symtab_and_line);
- init_sal (&lsal.sals.sals[0]);
- pending = 1;
- VEC_safe_push (linespec_sals, canonical.sals, &lsal);
- }
- break;
- default:
- throw_exception (e);
- }
- break;
- default:
- throw_exception (e);
+ /* At this point, either the user was queried about setting
+ a pending breakpoint and selected yes, or pending
+ breakpoint behavior is on and thus a pending breakpoint
+ is defaulted on behalf of the user. */
+ if (canonical->addr_string != NULL)
+ lsal.canonical = xstrdup (canonical->addr_string);
+ lsal.sals.nelts = 1;
+ lsal.sals.sals = XNEW (struct symtab_and_line);
+ init_sal (&lsal.sals.sals[0]);
+ pending = 1;
+ VEC_safe_push (linespec_sals, canonical->sals, &lsal);
}
-
- /* Create a chain of things that always need to be cleaned up. */
- old_chain = make_cleanup_destroy_linespec_result (&canonical);
-
- /* ----------------------------- SNIP -----------------------------
- Anything added to the cleanup chain beyond this point is assumed
- to be part of a breakpoint. If the breakpoint create succeeds
- then the memory is not reclaimed. */
- bkpt_chain = make_cleanup (null_cleanup, 0);
-
- /* Resolve all line numbers to PC's and verify that the addresses
- are ok for the target. */
- if (!pending)
+ else
{
int ix;
struct linespec_sals *iter;
- for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
+ /* Resolve all line numbers to PC's and verify that the addresses
+ are ok for the target. */
+ for (ix = 0; VEC_iterate (linespec_sals, canonical->sals, ix, iter); ++ix)
breakpoint_sals_to_pc (&iter->sals);
+
+ /* Verify that condition can be parsed, before setting any
+ breakpoints. Allocate a separate condition expression for each
+ breakpoint. */
+
+ if (parse_condition_and_thread)
+ {
+ char *rest;
+
+ /* Here we only parse 'arg' to separate condition
+ from thread number, so parsing in context of first
+ sal is OK. When setting the breakpoint we'll
+ re-parse it in context of each sal. */
+
+ iter = VEC_index (linespec_sals, canonical->sals, 0);
+
+ find_condition_and_thread (arg, iter->sals.sals[0].pc, &cond_string,
+ &thread, &task, &rest);
+ if (cond_string)
+ make_cleanup (xfree, cond_string);
+ if (rest)
+ make_cleanup (xfree, rest);
+ if (rest)
+ extra_string = rest;
+ }
+ else
+ {
+ /* Create a private copy of condition string. */
+ if (cond_string)
+ {
+ cond_string = xstrdup (cond_string);
+ make_cleanup (xfree, cond_string);
+ }
+ /* Create a private copy of any extra string. */
+ if (extra_string)
+ {
+ extra_string = xstrdup (extra_string);
+ make_cleanup (xfree, extra_string);
+ }
+ }
}
/* Fast tracepoints may have additional restrictions on location. */
@@ -9486,18 +9471,15 @@ create_breakpoint (struct gdbarch *gdbarch,
int ix;
struct linespec_sals *iter;
- for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
+ for (ix = 0; VEC_iterate (linespec_sals, canonical->sals, ix, iter); ++ix)
check_fast_tracepoint_sals (gdbarch, &iter->sals);
}
- /* Verify that condition can be parsed, before setting any
- breakpoints. Allocate a separate condition expression for each
- breakpoint. */
if (!pending)
{
struct linespec_sals *lsal;
- lsal = VEC_index (linespec_sals, canonical.sals, 0);
+ lsal = VEC_index (linespec_sals, canonical->sals, 0);
if (parse_condition_and_thread)
{
@@ -9532,7 +9514,7 @@ create_breakpoint (struct gdbarch *gdbarch,
}
}
- ops->create_breakpoints_sal (gdbarch, &canonical, lsal,
+ ops->create_breakpoints_sal (gdbarch, canonical, lsal,
cond_string, extra_string, type_wanted,
tempflag ? disp_del : disp_donttouch,
thread, task, ignore_count, ops,
@@ -9542,8 +9524,6 @@ create_breakpoint (struct gdbarch *gdbarch,
{
struct breakpoint *b;
- make_cleanup (xfree, copy_arg);
-
if (is_tracepoint_type (type_wanted))
{
struct tracepoint *t;
@@ -9556,7 +9536,8 @@ create_breakpoint (struct gdbarch *gdbarch,
init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
- b->addr_string = copy_arg;
+ if (canonical->addr_string)
+ b->addr_string = xstrdup (canonical->addr_string);
if (parse_condition_and_thread)
b->cond_string = NULL;
else
@@ -9580,8 +9561,8 @@ create_breakpoint (struct gdbarch *gdbarch,
install_breakpoint (internal, b, 0);
}
-
- if (VEC_length (linespec_sals, canonical.sals) > 1)
+
+ if (VEC_length (linespec_sals, canonical->sals) > 1)
{
warning (_("Multiple breakpoints were set.\nUse the "
"\"delete\" command to delete unwanted breakpoints."));
@@ -9591,8 +9572,6 @@ create_breakpoint (struct gdbarch *gdbarch,
/* That's it. Discard the cleanups for data inserted into the
breakpoint. */
discard_cleanups (bkpt_chain);
- /* But cleanup everything else. */
- do_cleanups (old_chain);
/* error call may happen here - have BKPT_CHAIN already discarded. */
update_global_location_list (1);
@@ -9600,6 +9579,79 @@ create_breakpoint (struct gdbarch *gdbarch,
return 1;
}
+/* Set a breakpoint. This function is shared between CLI and MI
+ functions for setting a breakpoint. This function has two major
+ modes of operations, selected by the PARSE_CONDITION_AND_THREAD
+ 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. 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, explicit_linespec *els,
+ char *arg, char *cond_string,
+ int thread, char *extra_string,
+ int parse_condition_and_thread,
+ int tempflag, enum bptype type_wanted,
+ int ignore_count,
+ enum auto_boolean pending_break_support,
+ const struct breakpoint_ops *ops,
+ int from_tty, int enabled, int internal,
+ unsigned flags)
+{
+ volatile struct gdb_exception e;
+ char *copy_arg = NULL;
+ char *addr_start = arg;
+ struct linespec_result canonical;
+ struct cleanup *back_to;
+ int result;
+
+ gdb_assert (ops != NULL);
+
+ init_linespec_result (&canonical);
+
+ TRY_CATCH (e, RETURN_MASK_ALL)
+ {
+ ops->create_sals_from_address (els, &arg, &canonical, type_wanted,
+ addr_start, ©_arg);
+ }
+
+ if (e.error == GDB_NO_ERROR)
+ {
+ if (VEC_empty (linespec_sals, canonical.sals))
+ return 0;
+ }
+ else if (e.error != NOT_FOUND_ERROR
+ || pending_break_support == AUTO_BOOLEAN_FALSE)
+ throw_exception (e);
+
+ if (canonical.sals == NULL)
+ {
+ /* Pending breakpoint is being set; print the exception. */
+ exception_print (gdb_stderr, e);
+ }
+
+ back_to = make_cleanup_destroy_linespec_result (&canonical);
+
+ if (canonical.addr_string == NULL)
+ {
+ if (addr_start)
+ canonical.addr_string = xstrdup (addr_start);
+ }
+
+ result = create_breakpoint_1 (gdbarch, &canonical, arg, cond_string,
+ thread, extra_string,
+ parse_condition_and_thread,
+ tempflag, type_wanted, ignore_count,
+ pending_break_support, ops, from_tty,
+ enabled, internal, flags);
+ do_cleanups (back_to);
+ return result;
+}
+
/* Set a breakpoint.
ARG is a string describing breakpoint address,
condition, and thread.
@@ -9624,7 +9676,7 @@ break_command_1 (char *arg, int flag, int from_tty)
ops = &bkpt_breakpoint_ops;
create_breakpoint (get_current_arch (),
- arg,
+ NULL, arg,
NULL, 0, NULL, 1 /* parse arg */,
tempflag, type_wanted,
0 /* Ignore count */,
@@ -9801,7 +9853,7 @@ void
dprintf_command (char *arg, int from_tty)
{
create_breakpoint (get_current_arch (),
- arg,
+ NULL, arg,
NULL, 0, NULL, 1 /* parse arg */,
0, bp_dprintf,
0 /* Ignore count */,
@@ -10026,7 +10078,7 @@ break_range_command (char *arg, int from_tty)
init_linespec_result (&canonical_start);
arg_start = arg;
- parse_breakpoint_sals (&arg, &canonical_start);
+ parse_breakpoint_sals (NULL, &arg, &canonical_start);
cleanup_bkpt = make_cleanup_destroy_linespec_result (&canonical_start);
@@ -11525,7 +11577,7 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
else
trigger_func_name = "__cxa_throw";
- create_breakpoint (get_current_arch (),
+ create_breakpoint (get_current_arch (), NULL,
trigger_func_name, cond_string, -1, NULL,
0 /* condition and thread are valid. */,
tempflag, bp_breakpoint,
@@ -12742,7 +12794,7 @@ base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
}
static void
-base_breakpoint_create_sals_from_address (char **arg,
+base_breakpoint_create_sals_from_address (explicit_linespec *els, char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start,
@@ -12769,8 +12821,8 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
}
static void
-base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
+base_breakpoint_decode_linespec (struct breakpoint *b, explicit_linespec *els,
+ char **s, struct symtabs_and_lines *sals)
{
internal_error_pure_virtual_called ();
}
@@ -12948,12 +13000,12 @@ bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
}
static void
-bkpt_create_sals_from_address (char **arg,
+bkpt_create_sals_from_address (explicit_linespec *els, 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,
+ create_sals_from_address_default (els, arg, canonical, type_wanted,
addr_start, copy_arg);
}
@@ -12980,10 +13032,10 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
}
static void
-bkpt_decode_linespec (struct breakpoint *b, char **s,
+bkpt_decode_linespec (struct breakpoint *b, explicit_linespec *els, char **s,
struct symtabs_and_lines *sals)
{
- decode_linespec_default (b, s, sals);
+ decode_linespec_default (b, els, s, sals);
}
/* Virtual table for internal breakpoints. */
@@ -13178,7 +13230,7 @@ bkpt_probe_remove_location (struct bp_location *bl)
}
static void
-bkpt_probe_create_sals_from_address (char **arg,
+bkpt_probe_create_sals_from_address (explicit_linespec *els, char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
@@ -13194,8 +13246,8 @@ bkpt_probe_create_sals_from_address (char **arg,
}
static void
-bkpt_probe_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
+bkpt_probe_decode_linespec (struct breakpoint *b, explicit_linespec *els,
+ char **s, struct symtabs_and_lines *sals)
{
*sals = parse_probes (s, NULL);
if (!sals->sals)
@@ -13287,12 +13339,12 @@ tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp)
}
static void
-tracepoint_create_sals_from_address (char **arg,
+tracepoint_create_sals_from_address (explicit_linespec *els, 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,
+ create_sals_from_address_default (els, arg, canonical, type_wanted,
addr_start, copy_arg);
}
@@ -13319,10 +13371,10 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
}
static void
-tracepoint_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
+tracepoint_decode_linespec (struct breakpoint *b, explicit_linespec *els,
+ char **s, struct symtabs_and_lines *sals)
{
- decode_linespec_default (b, s, sals);
+ decode_linespec_default (b, els, s, sals);
}
struct breakpoint_ops tracepoint_breakpoint_ops;
@@ -13331,22 +13383,22 @@ struct breakpoint_ops tracepoint_breakpoint_ops;
static probe. */
static void
-tracepoint_probe_create_sals_from_address (char **arg,
+tracepoint_probe_create_sals_from_address (explicit_linespec *els, char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
{
/* We use the same method for breakpoint on probes. */
- bkpt_probe_create_sals_from_address (arg, canonical, type_wanted,
+ bkpt_probe_create_sals_from_address (els, arg, canonical, type_wanted,
addr_start, copy_arg);
}
static void
-tracepoint_probe_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
+tracepoint_probe_decode_linespec (struct breakpoint *b, explicit_linespec *els,
+ char **s, struct symtabs_and_lines *sals)
{
/* We use the same method for breakpoint on probes. */
- bkpt_probe_decode_linespec (b, s, sals);
+ bkpt_probe_decode_linespec (b, els, s, sals);
}
static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
@@ -13355,7 +13407,7 @@ static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
markers (`-m'). */
static void
-strace_marker_create_sals_from_address (char **arg,
+strace_marker_create_sals_from_address (explicit_linespec *els, char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
@@ -13409,7 +13461,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
tp = XCNEW (struct tracepoint);
init_breakpoint_sal (&tp->base, gdbarch, expanded,
- addr_string, NULL,
+ NULL, addr_string, NULL,
cond_string, extra_string,
type_wanted, disposition,
thread, task, ignore_count, ops,
@@ -13430,8 +13482,8 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
}
static void
-strace_marker_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
+strace_marker_decode_linespec (struct breakpoint *b, explicit_linespec *els,
+ char **s, struct symtabs_and_lines *sals)
{
struct tracepoint *tp = (struct tracepoint *) b;
@@ -13980,11 +14032,13 @@ update_breakpoint_locations (struct breakpoint *b,
update_global_location_list (1);
}
-/* Find the SaL locations corresponding to the given ADDR_STRING.
- On return, FOUND will be 1 if any SaL was found, zero otherwise. */
+/* Find the SaL locations corresponding to the given explicit linespec,
+ ELS, or address string, ADDR_STRING. On return, FOUND will be 1 if
+ any SaL was found, zero otherwise. */
static struct symtabs_and_lines
-addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
+addr_string_to_sals (struct breakpoint *b, explicit_linespec *els,
+ char *addr_string, int *found)
{
char *s;
struct symtabs_and_lines sals = {0};
@@ -13995,7 +14049,7 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
TRY_CATCH (e, RETURN_MASK_ERROR)
{
- b->ops->decode_linespec (b, &s, &sals);
+ b->ops->decode_linespec (b, els, &s, &sals);
}
if (e.reason < 0)
{
@@ -14073,7 +14127,8 @@ breakpoint_re_set_default (struct breakpoint *b)
struct symtabs_and_lines expanded = {0};
struct symtabs_and_lines expanded_end = {0};
- sals = addr_string_to_sals (b, b->addr_string, &found);
+ sals = addr_string_to_sals (b, NULL, b->addr_string, &found);
+
if (found)
{
make_cleanup (xfree, sals.sals);
@@ -14082,7 +14137,8 @@ breakpoint_re_set_default (struct breakpoint *b)
if (b->addr_string_range_end)
{
- sals_end = addr_string_to_sals (b, b->addr_string_range_end, &found);
+ sals_end = addr_string_to_sals (b, NULL, b->addr_string_range_end,
+ &found);
if (found)
{
make_cleanup (xfree, sals_end.sals);
@@ -14097,12 +14153,12 @@ breakpoint_re_set_default (struct breakpoint *b)
calls parse_breakpoint_sals. Return 1 for success, zero for failure. */
static void
-create_sals_from_address_default (char **arg,
+create_sals_from_address_default (explicit_linespec *els, char **arg,
struct linespec_result *canonical,
enum bptype type_wanted,
char *addr_start, char **copy_arg)
{
- parse_breakpoint_sals (arg, canonical);
+ parse_breakpoint_sals (els, arg, canonical);
}
/* Call create_breakpoints_sal for the given arguments. This is the default
@@ -14134,8 +14190,8 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
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)
+decode_linespec_default (struct breakpoint *b, explicit_linespec *els,
+ char **s, struct symtabs_and_lines *sals)
{
struct linespec_result canonical;
@@ -14976,7 +15032,7 @@ trace_command (char *arg, int from_tty)
ops = &tracepoint_breakpoint_ops;
if (create_breakpoint (get_current_arch (),
- arg,
+ NULL, arg,
NULL, 0, NULL, 1 /* parse arg */,
0 /* tempflag */,
bp_tracepoint /* type_wanted */,
@@ -14993,7 +15049,7 @@ static void
ftrace_command (char *arg, int from_tty)
{
if (create_breakpoint (get_current_arch (),
- arg,
+ NULL, arg,
NULL, 0, NULL, 1 /* parse arg */,
0 /* tempflag */,
bp_fast_tracepoint /* type_wanted */,
@@ -15021,7 +15077,7 @@ strace_command (char *arg, int from_tty)
ops = &tracepoint_breakpoint_ops;
if (create_breakpoint (get_current_arch (),
- arg,
+ NULL, arg,
NULL, 0, NULL, 1 /* parse arg */,
0 /* tempflag */,
bp_static_tracepoint /* type_wanted */,
@@ -15086,7 +15142,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
utp->number);
if (!create_breakpoint (get_current_arch (),
- addr_str,
+ NULL, addr_str,
utp->cond_string, -1, NULL,
0 /* parse cond/thread */,
0 /* tempflag */,
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 4e4f875..43be84a 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -34,6 +34,7 @@ struct bpstats;
struct bp_location;
struct linespec_result;
struct linespec_sals;
+struct explicit_linespec;
/* 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
@@ -563,7 +564,8 @@ struct breakpoint_ops
`create_sals_from_address_default'.
This function is called inside `create_breakpoint'. */
- void (*create_sals_from_address) (char **, struct linespec_result *,
+ void (*create_sals_from_address) (struct explicit_linespec *, char **,
+ struct linespec_result *,
enum bptype, char *, char **);
/* This method will be responsible for creating a breakpoint given its SALs.
@@ -581,13 +583,13 @@ struct breakpoint_ops
int, const struct breakpoint_ops *,
int, int, int, unsigned);
- /* 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'.
+ /* Given an explicit linespec (second parameter) or address string
+ (third 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 *);
+ void (*decode_linespec) (struct breakpoint *, struct explicit_linespec *,
+ char **, struct symtabs_and_lines *);
};
/* Helper for breakpoint_ops->print_recreate implementations. Prints
@@ -1233,7 +1235,8 @@ enum breakpoint_create_flags
CREATE_BREAKPOINT_FLAGS_INSERTED = 1 << 0
};
-extern int create_breakpoint (struct gdbarch *gdbarch, char *arg,
+extern int create_breakpoint (struct gdbarch *gdbarch,
+ struct explicit_linespec *els, char *arg,
char *cond_string, int thread,
char *extra_string,
int parse_condition_and_thread,
diff --git a/gdb/linespec.h b/gdb/linespec.h
index 0310bb4..51b111b 100644
--- a/gdb/linespec.h
+++ b/gdb/linespec.h
@@ -53,6 +53,27 @@ struct linespec_sals
typedef struct linespec_sals linespec_sals;
DEF_VEC_O (linespec_sals);
+/* A description of an explicit linespec. */
+
+struct explicit_linespec
+{
+ /* An expression, *expr */
+ const char *expression;
+
+ /* The source filename */
+ const char *source_filename;
+
+ /* The function name */
+ const char *function_name;
+
+ /* The name of a label */
+ const char *label_name;
+
+ /* An offset */
+ const char *offset;
+};
+typedef struct explicit_linespec explicit_linespec;
+
/* An instance of this may be filled in by decode_line_1. The caller
must call init_linespec_result to initialize it and
destroy_linespec_result to destroy it. The caller must make copies
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
index 5a64bf1..52ea90c 100644
--- a/gdb/mi/mi-cmd-break.c
+++ b/gdb/mi/mi-cmd-break.c
@@ -163,8 +163,8 @@ mi_cmd_break_insert (char *command, char **argv, int argc)
? (hardware ? bp_fast_tracepoint : bp_tracepoint)
: (hardware ? bp_hardware_breakpoint : bp_breakpoint));
- create_breakpoint (get_current_arch (), address, condition, thread,
- NULL,
+ create_breakpoint (get_current_arch (), NULL, address, condition, thread,
+ NULL /* extra_string */,
0 /* condition and thread are valid. */,
temp_p, type_wanted,
ignore_count,
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 89ace99..a07b55e 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -622,7 +622,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
case bp_breakpoint:
{
create_breakpoint (python_gdbarch,
- copy, NULL, -1, NULL,
+ NULL, copy, NULL, -1, NULL,
0,
0, bp_breakpoint,
0,
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 56ab775..6a2bc09 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -287,7 +287,7 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
addr_str = small_buf;
create_breakpoint (python_gdbarch,
- addr_str, NULL, thread, NULL,
+ NULL, addr_str, NULL, thread, NULL,
0,
1 /*temp_flag*/,
bp_breakpoint,
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index f05a26b..d6d17b0 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1941,7 +1941,8 @@ spu_catch_start (struct objfile *objfile)
/* Use a numerical address for the set_breakpoint command to avoid having
the breakpoint re-set incorrectly. */
xsnprintf (buf, sizeof buf, "*%s", core_addr_to_string (pc));
- create_breakpoint (get_objfile_arch (objfile), buf /* arg */,
+ create_breakpoint (get_objfile_arch (objfile),
+ NULL /* explicit */, buf /* arg */,
NULL /* cond_string */, -1 /* thread */,
NULL /* extra_string */,
0 /* parse_condition_and_thread */, 1 /* tempflag */,