[RFA,5/9] Explicit locations v2 - Add probe locations

Message ID 536BC69E.9060008@redhat.com
State Superseded
Headers

Commit Message

Keith Seitz May 8, 2014, 6:02 p.m. UTC
  Hi,

This patch adds support for probe locations. This is a new location type 
that I added in this v2 revision of this series.

Like the previous patch for address locations, this patch does not add 
any new functionality. It is also "simply" an elaboration of the new 
location API.

Keith

ChangeLog
2014-05-08  Keith Seitz  <keiths@redhat.com>

	* 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): Handel probe locations.
	* location.h (enum event_location_type): Add EVENT_LOCATION_PROBE.
	(EVENT_LOCATION_PROBE): Define accessor macro.
	* probe.c (parse_probes): Assert that LOCATION is a probe location.
	Convert linespec into probe location.
  

Patch

diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 31cce47..e352935 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -214,8 +214,8 @@  re_set_exception_catchpoint (struct breakpoint *self)
     {
       struct event_location location;
 
-      initialize_event_location (&location, EVENT_LOCATION_LINESPEC);
-      EVENT_LOCATION_LINESPEC (&location)
+      initialize_event_location (&location, EVENT_LOCATION_PROBE);
+      EVENT_LOCATION_PROBE (&location)
 	= ASTRDUP (exception_functions[kind].probe);
       sals = parse_probes (&location, NULL);
     }
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f509d7a..fdf7c10 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -3387,8 +3387,8 @@  create_longjmp_master_breakpoint (void)
 								 objfile),
 					      bp_longjmp_master,
 					      &internal_breakpoint_ops);
-	      b->location = new_event_location (EVENT_LOCATION_LINESPEC);
-	      EVENT_LOCATION_LINESPEC (b->location)
+	      b->location = new_event_location (EVENT_LOCATION_PROBE);
+	      EVENT_LOCATION_PROBE (b->location)
 		= xstrdup ("-probe-stap libc:longjmp");
 	      b->enable_state = bp_disabled;
 	    }
@@ -3554,8 +3554,8 @@  create_exception_master_breakpoint (void)
 								 objfile),
 					      bp_exception_master,
 					      &internal_breakpoint_ops);
-	      b->location = new_event_location (EVENT_LOCATION_LINESPEC);
-	      EVENT_LOCATION_LINESPEC (b->location)
+	      b->location = new_event_location (EVENT_LOCATION_PROBE);
+	      EVENT_LOCATION_PROBE (b->location)
 		= xstrdup ("-probe-stap libgcc:unwind");
 	      b->enable_state = bp_disabled;
 	    }
@@ -10086,7 +10086,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;
 
@@ -10094,7 +10093,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) == EVENT_LOCATION_PROBE)
     ops = &bkpt_probe_breakpoint_ops;
   else
     ops = &bkpt_breakpoint_ops;
@@ -15471,11 +15471,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) == EVENT_LOCATION_PROBE)
     ops = &tracepoint_probe_breakpoint_ops;
   else
     ops = &tracepoint_breakpoint_ops;
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 07a84b5..069aab6 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -2457,6 +2457,11 @@  event_location_to_sals (linespec_parser *parser,
 					    EVENT_LOCATION_ADDRESS (location));
       break;
 
+    case EVENT_LOCATION_PROBE:
+      /* 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 22e7496..a64d37c 100644
--- a/gdb/location.c
+++ b/gdb/location.c
@@ -72,6 +72,10 @@  copy_event_location (const struct event_location *src)
       EVENT_LOCATION_ADDRESS (dst) = EVENT_LOCATION_ADDRESS (src);
       break;
 
+    case EVENT_LOCATION_PROBE:
+      EVENT_LOCATION_PROBE (dst) = xstrdup (EVENT_LOCATION_PROBE (src));
+      break;
+
     default:
       gdb_assert_not_reached ("unknown event location type");
     }
@@ -101,6 +105,10 @@  delete_event_location (void *data)
 	  /* Nothing to do.  */
 	  break;
 
+	case EVENT_LOCATION_PROBE:
+	  xfree (EVENT_LOCATION_PROBE (location));
+	  break;
+
 	default:
 	  gdb_assert_not_reached ("unknown event location type");
 	}
@@ -128,6 +136,10 @@  event_location_to_string (const struct event_location *location)
       result = EVENT_LOCATION_SAVE_SPEC (location);
       break;
 
+    case EVENT_LOCATION_PROBE:
+      result = EVENT_LOCATION_PROBE (location);
+      break;
+
     default:
       gdb_assert_not_reached ("unknown event location type");
     }
@@ -158,12 +170,28 @@  string_to_event_location (char **stringp,
     }
   else
     {
-      /* Everything else is a linespec.  */
-      location = new_event_location (EVENT_LOCATION_LINESPEC);
-      if (*stringp != NULL)
+      const char *cs;
+
+      /* Next, try the input as a probe spec.  */
+      cs = *stringp;
+      if (cs != NULL && probe_linespec_to_ops (&cs) != NULL)
 	{
-	  EVENT_LOCATION_LINESPEC (location) = xstrdup (*stringp);
-	  *stringp += strlen (*stringp);
+	  location = new_event_location (EVENT_LOCATION_PROBE);
+	  if (*stringp != NULL)
+	    {
+	      EVENT_LOCATION_PROBE (location) = xstrdup (*stringp);
+	      *stringp += strlen (*stringp);
+	    }
+	}
+      else
+	{
+	  /* Everything else is a linespec.  */
+	  location = new_event_location (EVENT_LOCATION_LINESPEC);
+	  if (*stringp != NULL)
+	    {
+	      EVENT_LOCATION_LINESPEC (location) = xstrdup (*stringp);
+	      *stringp += strlen (*stringp);
+	    }
 	}
     }
 
@@ -183,6 +211,9 @@  event_location_empty_p (const struct event_location *location)
     case EVENT_LOCATION_ADDRESS:
       return 0;
 
+    case EVENT_LOCATION_PROBE:
+      return EVENT_LOCATION_PROBE (location) == NULL;
+
     default:
       gdb_assert_not_reached ("unknown event location type");
     }
diff --git a/gdb/location.h b/gdb/location.h
index 8575daf..b207c87 100644
--- a/gdb/location.h
+++ b/gdb/location.h
@@ -30,7 +30,10 @@  enum event_location_type
   EVENT_LOCATION_LINESPEC,
 
   /* An address in the inferior.  */
-  EVENT_LOCATION_ADDRESS
+  EVENT_LOCATION_ADDRESS,
+
+  /* A probe location.  */
+  EVENT_LOCATION_PROBE
 };
 
 /* An event location used to set a stop event in the inferior.
@@ -50,6 +53,7 @@  struct event_location
        probes.  */
     char *addr_string;
 #define EVENT_LOCATION_LINESPEC(S) ((S)->u.addr_string)
+#define EVENT_LOCATION_PROBE(S) ((S)->u.addr_string)
 
     /* An address in the inferior.  */
     CORE_ADDR address;
diff --git a/gdb/probe.c b/gdb/probe.c
index f7afe0b..82bcdab 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 = EVENT_LOCATION_LINESPEC (location);
+  gdb_assert (EVENT_LOCATION_TYPE (location) == EVENT_LOCATION_PROBE);
+  arg_start = EVENT_LOCATION_PROBE (location);
 
   cs = arg_start;
   probe_ops = probe_linespec_to_ops (&cs);
@@ -173,12 +174,12 @@  parse_probes (struct event_location *location,
     {
       canonical->special_display = 1;
       canonical->pre_expanded = 1;
-      canonical->location = new_event_location (EVENT_LOCATION_LINESPEC);
-      EVENT_LOCATION_LINESPEC (canonical->location)
+      canonical->location = new_event_location (EVENT_LOCATION_PROBE);
+      EVENT_LOCATION_PROBE (canonical->location)
 	= savestring (arg_start, arg_end - arg_start);
     }
 
-  EVENT_LOCATION_LINESPEC (location) = arg_end;
+  EVENT_LOCATION_PROBE (location) = arg_end;
   do_cleanups (cleanup);
 
   return result;