gdb/ChangeLog: * break-catch-throw.c (re_set_exception_catchpoint): Convert linespec for stap probe to probe location. * breakpoint.c (create_longjmp_master_breakpoint): Likewise. (create_exception_master_breakpoint): Likewise. (break_command_1): Remove local variable `arg_cp'. Check location type to set appropriate breakpoint ops methods. (trace_command): Likewise. * linespec.c (event_location_to_sals): Handle probe locations. * location.c (copy_event_location): Likewise. (delete_event_location): Likewise. (event_location_to_string): Likewise. (string_to_event_location): Likewise. (event_location_empty_p): Likewise. * location.h (enum event_location_type): Add PROBE_LOCATION. * probe.c (parse_probes): Assert that LOCATION is a probe location. Convert linespec into probe location. --- gdb/break-catch-throw.c | 2 + gdb/breakpoint.c | 12 ++++----- gdb/linespec.c | 5 ++++ gdb/location.c | 64 ++++++++++++++++++++++++++++++++++++++++++++--- gdb/location.h | 17 ++++++++++++ gdb/probe.c | 7 +++-- 6 files changed, 92 insertions(+), 15 deletions(-) diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 098ab1a..57b18ad 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -212,7 +212,7 @@ re_set_exception_catchpoint (struct breakpoint *self) /* We first try to use the probe interface. */ location - = new_linespec_location (ASTRDUP (exception_functions[kind].probe)); + = new_probe_location (ASTRDUP (exception_functions[kind].probe)); cleanup = make_cleanup_delete_event_location (location); copy_location = copy_event_location_tmp (location); make_cleanup (xfree, copy_location); diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 395e0f4..0fceeac 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3387,7 +3387,7 @@ create_longjmp_master_breakpoint (void) bp_longjmp_master, &internal_breakpoint_ops); b->location - = new_linespec_location ("-probe-stap libc:longjmp"); + = new_probe_location ("-probe-stap libc:longjmp"); b->enable_state = bp_disabled; } @@ -3551,7 +3551,7 @@ create_exception_master_breakpoint (void) bp_exception_master, &internal_breakpoint_ops); b->location - = new_linespec_location ("-probe-stap libgcc:unwind"); + = new_probe_location ("-probe-stap libgcc:unwind"); b->enable_state = bp_disabled; } @@ -10082,7 +10082,6 @@ break_command_1 (char *arg, int flag, int from_tty) ? bp_hardware_breakpoint : bp_breakpoint); struct breakpoint_ops *ops; - const char *arg_cp = arg; struct event_location *location; struct cleanup *cleanup; @@ -10090,7 +10089,8 @@ break_command_1 (char *arg, int flag, int from_tty) cleanup = make_cleanup_delete_event_location (location); /* Matching breakpoints on probes. */ - if (arg_cp != NULL && probe_linespec_to_ops (&arg_cp) != NULL) + if (location != NULL + && event_location_type (location) == PROBE_LOCATION) ops = &bkpt_probe_breakpoint_ops; else ops = &bkpt_breakpoint_ops; @@ -15453,11 +15453,11 @@ trace_command (char *arg, int from_tty) struct breakpoint_ops *ops; struct event_location *location; struct cleanup *back_to; - const char *arg_cp = arg; location = string_to_event_location (&arg, current_language); back_to = make_cleanup_delete_event_location (location); - if (arg_cp != NULL && probe_linespec_to_ops (&arg_cp) != NULL) + if (location != NULL + && event_location_type (location) == PROBE_LOCATION) ops = &tracepoint_probe_breakpoint_ops; else ops = &tracepoint_breakpoint_ops; diff --git a/gdb/linespec.c b/gdb/linespec.c index 7048d02..bc4484f 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -2433,6 +2433,11 @@ event_location_to_sals (linespec_parser *parser, get_address_location (location)); break; + case PROBE_LOCATION: + /* Probes are handled by their own decoders. */ + gdb_assert_not_reached ("attempt to decode probe location"); + break; + default: gdb_assert_not_reached ("unhandled event location type"); } diff --git a/gdb/location.c b/gdb/location.c index 9e86107..8d8fa89 100644 --- a/gdb/location.c +++ b/gdb/location.c @@ -45,6 +45,7 @@ struct event_location probes. */ char *addr_string; #define EL_LINESPEC(PTR) ((PTR)->u.addr_string) +#define EL_PROBE(PTR) ((PTR)->u.addr_string) /* An address in the inferior. */ CORE_ADDR address; @@ -113,6 +114,29 @@ get_address_location (struct event_location *location) /* See description in location.h. */ struct event_location * +new_probe_location (const char *probe) +{ + struct event_location *location; + + location = XCNEW (struct event_location); + EL_TYPE (location) = PROBE_LOCATION; + if (probe != NULL) + EL_PROBE (location) = xstrdup (probe); + return location; +} + +/* See description in location.h. */ + +char * +get_probe_location (struct event_location *location) +{ + gdb_assert (EL_TYPE (location) == PROBE_LOCATION); + return EL_PROBE (location); +} + +/* See description in location.h. */ + +struct event_location * copy_event_location (const struct event_location *src) { struct event_location *dst; @@ -133,6 +157,11 @@ copy_event_location (const struct event_location *src) EL_ADDRESS (dst) = EL_ADDRESS (src); break; + case PROBE_LOCATION: + if (EL_PROBE (src) != NULL) + EL_PROBE (dst) = xstrdup (EL_PROBE (src)); + break; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -177,6 +206,10 @@ delete_event_location (struct event_location *location) /* Nothing to do. */ break; + case PROBE_LOCATION: + xfree (EL_PROBE (location)); + break; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -219,6 +252,10 @@ event_location_to_string_const (const struct event_location *location) core_addr_to_string (EL_ADDRESS (location))); break; + case PROBE_LOCATION: + result = xstrdup (EL_PROBE (location)); + break; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -259,10 +296,22 @@ string_to_event_location (char **stringp, } else { - /* Everything else is a linespec. */ - location = new_linespec_location (*stringp); - if (*stringp != NULL) - *stringp += strlen (*stringp); + const char *cs; + + /* Next, try the input as a probe spec. */ + cs = *stringp; + if (cs != NULL && probe_linespec_to_ops (&cs) != NULL) + { + location = new_probe_location (*stringp); + *stringp += strlen (*stringp); + } + else + { + /* Everything else is a linespec. */ + location = new_linespec_location (*stringp); + if (*stringp != NULL) + *stringp += strlen (*stringp); + } } return location; @@ -282,6 +331,9 @@ event_location_empty_p (const struct event_location *location) case ADDRESS_LOCATION: return 0; + case PROBE_LOCATION: + return EL_PROBE (location) == NULL; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -294,6 +346,8 @@ void event_location_advance_input_ptr (char **inp, { if (EL_TYPE (location) == LINESPEC_LOCATION) *inp = EL_LINESPEC (location); + else if (EL_TYPE (location) == PROBE_LOCATION) + *inp = EL_PROBE (location); } /* See description in location.h. */ @@ -303,6 +357,8 @@ advance_event_location_ptr (struct event_location *location, size_t num) { if (EL_TYPE (location) == LINESPEC_LOCATION) EL_LINESPEC (location) += num; + else if (EL_TYPE (location) == PROBE_LOCATION) + EL_PROBE (location) += num; } /* See description in location.h. */ diff --git a/gdb/location.h b/gdb/location.h index 14aaffa..fa4d0f5 100644 --- a/gdb/location.h +++ b/gdb/location.h @@ -31,7 +31,10 @@ enum event_location_type LINESPEC_LOCATION, /* An address in the inferior. */ - ADDRESS_LOCATION + ADDRESS_LOCATION, + + /* A probe location. */ + PROBE_LOCATION }; /* Return the type of the given event location. */ @@ -79,6 +82,18 @@ extern struct event_location * extern CORE_ADDR get_address_location (struct event_location *location); +/* Create a new probe location. The return result is malloc'd + and should be freed with delete_event_location. */ + +extern struct event_location * + new_probe_location (const char *probe); + +/* Return the probe location (a string) of the given event_location + (which must be of type PROBE_LOCATION). */ + +extern char * + get_probe_location (struct event_location *location); + /* Free an event location and any associated data. */ extern void delete_event_location (struct event_location *location); diff --git a/gdb/probe.c b/gdb/probe.c index edf16f7..e28082e 100644 --- a/gdb/probe.c +++ b/gdb/probe.c @@ -58,7 +58,8 @@ parse_probes (struct event_location *location, result.sals = NULL; result.nelts = 0; - arg_start = get_linespec_location (location); + gdb_assert (event_location_type (location) == PROBE_LOCATION); + arg_start = get_probe_location (location); cs = arg_start; probe_ops = probe_linespec_to_ops (&cs); @@ -175,11 +176,11 @@ parse_probes (struct event_location *location, canonical->special_display = 1; canonical->pre_expanded = 1; - canonical->location = new_linespec_location (canon); + canonical->location = new_probe_location (canon); xfree (canon); } - /* Advance the location past all parsed input. */ + /* Advance the probe location past all parsed input. */ advance_event_location_ptr (location, arg_end - arg_start); do_cleanups (cleanup);