From 5b56227bdc000d129d393772f1e4544b5ea0fd46 Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Tue, 11 Aug 2015 17:09:35 -0700 Subject: [PATCH] Explicit locations: introduce probe locations This patch adds support for probe locations and converts existing probe linespec locations to the new location type. gdb/ChangeLog: * break-catch-throw.c (re_set_exception_catchpoint): Convert linespec for stap probe to probe location. * breakpoint.c (create_longjmp_master_breakpoint) (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): Assert on probe locations. * location.c (EL_PROBE): Add macro definition. (new_probe_location, get_probe_location): New functions. (copy_event_location, delete_event_location, event_location_to_string) (string_to_event_location, event_location_empty_p): Handle probe locations. * location.h (enum event_location_type): Add PROBE_LOCATION. (new_probe_location, get_probe_location): Declare. * probe.c (parse_probes): Assert that LOCATION is a probe location. Convert linespec into probe location. --- gdb/ChangeLog | 20 ++++++++++++++++++ gdb/break-catch-throw.c | 5 ++--- gdb/breakpoint.c | 18 +++++++--------- gdb/linespec.c | 5 +++++ gdb/location.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++-- gdb/location.h | 17 ++++++++++++++- gdb/probe.c | 5 +++-- 7 files changed, 108 insertions(+), 18 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 97da8c5..efb0587 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,25 @@ 2015-08-11 Keith Seitz + * break-catch-throw.c (re_set_exception_catchpoint): Convert + linespec for stap probe to probe location. + * breakpoint.c (create_longjmp_master_breakpoint) + (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): Assert on probe locations. + * location.c (EL_PROBE): Add macro definition. + (new_probe_location, get_probe_location): New functions. + (copy_event_location, delete_event_location, event_location_to_string) + (string_to_event_location, event_location_empty_p): Handle probe + locations. + * location.h (enum event_location_type): Add PROBE_LOCATION. + (new_probe_location, get_probe_location): Declare. + * probe.c (parse_probes): Assert that LOCATION is a probe location. + Convert linespec into probe location. + +2015-08-11 Keith Seitz + * breakpoint.c (create_thread_event_breakpoint, init_breakpoint_sal): Convert linespec to address location. * linespec.c (canonicalize_linespec): Do not handle address diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 9449aa5..07a8f05 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -216,9 +216,8 @@ re_set_exception_catchpoint (struct breakpoint *self) /* We first try to use the probe interface. */ TRY { - char *spec = ASTRDUP (exception_functions[kind].probe); - - location = new_linespec_location (&spec); + location + = new_probe_location (exception_functions[kind].probe); cleanup = make_cleanup_delete_event_location (location); sals = parse_probes (location, NULL); do_cleanups (cleanup); diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index b05c93a..0597688 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3517,7 +3517,6 @@ create_longjmp_master_breakpoint (void) int i; struct probe *probe; struct gdbarch *gdbarch = get_objfile_arch (objfile); - char *p; for (i = 0; VEC_iterate (probe_p, @@ -3532,8 +3531,8 @@ create_longjmp_master_breakpoint (void) objfile), bp_longjmp_master, &internal_breakpoint_ops); - p = ASTRDUP ("-probe-stap libc:longjmp"); - b->location = new_linespec_location (&p); + b->location + = new_probe_location ("-probe-stap libc:longjmp"); b->enable_state = bp_disabled; } @@ -3695,15 +3694,14 @@ create_exception_master_breakpoint (void) ++i) { struct breakpoint *b; - char *p; b = create_internal_breakpoint (gdbarch, get_probe_address (probe, objfile), bp_exception_master, &internal_breakpoint_ops); - p = ASTRDUP ("-probe-stap libgcc:unwind"); - b->location = new_linespec_location (&p); + b->location + = new_probe_location ("-probe-stap libgcc:unwind"); b->enable_state = bp_disabled; } @@ -9850,7 +9848,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; @@ -9858,7 +9855,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; @@ -14983,11 +14981,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 65c55df..8a7640b 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -2479,6 +2479,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 eea88fa..fd35c48 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; @@ -121,6 +122,29 @@ get_address_location (const 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. */ + +const char * +get_probe_location (const 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; @@ -141,6 +165,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"); } @@ -185,6 +214,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"); } @@ -213,6 +246,10 @@ event_location_to_string (struct event_location *location) core_addr_to_string (EL_ADDRESS (location))); break; + case PROBE_LOCATION: + EL_STRING (location) = xstrdup (EL_PROBE (location)); + break; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -242,8 +279,20 @@ string_to_event_location (char **stringp, } else { - /* Everything else is a linespec. */ - location = new_linespec_location (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); + } } return location; @@ -263,6 +312,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"); } diff --git a/gdb/location.h b/gdb/location.h index 7b9741b..63318ba 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. */ @@ -72,6 +75,18 @@ extern struct event_location * extern CORE_ADDR get_address_location (const 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 const char * + get_probe_location (const 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 8366220..a3cfefe 100644 --- a/gdb/probe.c +++ b/gdb/probe.c @@ -59,7 +59,8 @@ parse_probes (const 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); @@ -178,7 +179,7 @@ parse_probes (const struct event_location *location, make_cleanup (xfree, canon); canonical->special_display = 1; canonical->pre_expanded = 1; - canonical->location = new_linespec_location (&canon); + canonical->location = new_probe_location (canon); } do_cleanups (cleanup); -- 2.7.4