Add support for enabling and disabling tracepoints while a trace
[deliverable/binutils-gdb.git] / gdb / gdbserver / tracepoint.c
index fc9c7d89f4fb0cc1581bf1252ef6d68aec4ac907..dc1050e4c7412809e3be0ad6f420fa9d5f0bd524 100644 (file)
@@ -2214,9 +2214,6 @@ clear_installed_tracepoints (void)
   /* Restore any bytes overwritten by tracepoints.  */
   for (tpoint = tracepoints; tpoint; tpoint = tpoint->next)
     {
-      if (!tpoint->enabled)
-       continue;
-
       /* Catch the case where we might try to remove a tracepoint that
         was never actually installed.  */
       if (tpoint->handle == NULL)
@@ -2454,6 +2451,73 @@ cmd_qtdv (char *own_buf)
   write_ok (own_buf);
 }
 
+static void
+cmd_qtenable_disable (char *own_buf, int enable)
+{
+  char *packet = own_buf;
+  ULONGEST num, addr;
+  struct tracepoint *tp;
+
+  packet += strlen (enable ? "QTEnable:" : "QTDisable:");
+  packet = unpack_varlen_hex (packet, &num);
+  ++packet; /* skip a colon */
+  packet = unpack_varlen_hex (packet, &addr);
+
+  tp = find_tracepoint (num, addr);
+
+  if (tp)
+    {
+      if ((enable && tp->enabled) || (!enable && !tp->enabled))
+       {
+         trace_debug ("Tracepoint %d at 0x%s is already %s",
+                      (int) num, paddress (addr),
+                      enable ? "enabled" : "disabled");
+         write_ok (own_buf);
+         return;
+       }
+
+      trace_debug ("%s tracepoint %d at 0x%s",
+                  enable ? "Enabling" : "Disabling",
+                  (int) num, paddress (addr));
+
+      tp->enabled = enable;
+
+      if (tp->type == fast_tracepoint || tp->type == static_tracepoint)
+       {
+         int ret;
+         int offset = offsetof (struct tracepoint, enabled);
+         CORE_ADDR obj_addr = tp->obj_addr_on_target + offset;
+
+         ret = prepare_to_access_memory ();
+         if (ret)
+           {
+             trace_debug ("Failed to temporarily stop inferior threads");
+             write_enn (own_buf);
+             return;
+           }
+         
+         ret = write_inferior_integer (obj_addr, enable);
+         done_accessing_memory ();
+         
+         if (ret)
+           {
+             trace_debug ("Cannot write enabled flag into "
+                          "inferior process memory");
+             write_enn (own_buf);
+             return;
+           }
+       }
+
+      write_ok (own_buf);
+    }
+  else
+    {
+      trace_debug ("Tracepoint %d at 0x%s not found",
+                  (int) num, paddress (addr));
+      write_enn (own_buf);
+    }
+}
+
 static void
 cmd_qtv (char *own_buf)
 {
@@ -2463,7 +2527,7 @@ cmd_qtv (char *own_buf)
   char *packet = own_buf;
 
   packet += strlen ("qTV:");
-  packet = unpack_varlen_hex (packet, &num);
+  unpack_varlen_hex (packet, &num);
 
   if (current_traceframe >= 0)
     {
@@ -2719,9 +2783,6 @@ cmd_qtstart (char *packet)
       /* Ensure all the hit counts start at zero.  */
       tpoint->hit_count = 0;
 
-      if (!tpoint->enabled)
-       continue;
-
       if (tpoint->type == trap_tracepoint)
        {
          ++slow_tracepoint_count;
@@ -3033,7 +3094,7 @@ cmd_qtframe (char *own_buf)
   if (strncmp (packet, "pc:", strlen ("pc:")) == 0)
     {
       packet += strlen ("pc:");
-      packet = unpack_varlen_hex (packet, &pc);
+      unpack_varlen_hex (packet, &pc);
       trace_debug ("Want to find next traceframe at pc=0x%s", paddress (pc));
       tframe = find_next_traceframe_in_range (pc, pc, 1, &tfnum);
     }
@@ -3042,7 +3103,7 @@ cmd_qtframe (char *own_buf)
       packet += strlen ("range:");
       packet = unpack_varlen_hex (packet, &lo);
       ++packet;
-      packet = unpack_varlen_hex (packet, &hi);
+      unpack_varlen_hex (packet, &hi);
       trace_debug ("Want to find next traceframe in the range 0x%s to 0x%s",
                   paddress (lo), paddress (hi));
       tframe = find_next_traceframe_in_range (lo, hi, 1, &tfnum);
@@ -3052,7 +3113,7 @@ cmd_qtframe (char *own_buf)
       packet += strlen ("outside:");
       packet = unpack_varlen_hex (packet, &lo);
       ++packet;
-      packet = unpack_varlen_hex (packet, &hi);
+      unpack_varlen_hex (packet, &hi);
       trace_debug ("Want to find next traceframe "
                   "outside the range 0x%s to 0x%s",
                   paddress (lo), paddress (hi));
@@ -3061,7 +3122,7 @@ cmd_qtframe (char *own_buf)
   else if (strncmp (packet, "tdp:", strlen ("tdp:")) == 0)
     {
       packet += strlen ("tdp:");
-      packet = unpack_varlen_hex (packet, &num);
+      unpack_varlen_hex (packet, &num);
       tpnum = (int) num;
       trace_debug ("Want to find next traceframe for tracepoint %d", tpnum);
       tframe = find_next_traceframe_by_tracepoint (tpnum, &tfnum);
@@ -3383,7 +3444,7 @@ cmd_qtbuffer (char *own_buf)
 
   packet = unpack_varlen_hex (packet, &offset);
   ++packet; /* skip a comma */
-  packet = unpack_varlen_hex (packet, &num);
+  unpack_varlen_hex (packet, &num);
 
   trace_debug ("Want to get trace buffer, %d bytes at offset 0x%s",
               (int) num, pulongest (offset));
@@ -3433,7 +3494,7 @@ cmd_bigqtbuffer (char *own_buf)
   if (strncmp ("circular:", packet, strlen ("circular:")) == 0)
     {
       packet += strlen ("circular:");
-      packet = unpack_varlen_hex (packet, &val);
+      unpack_varlen_hex (packet, &val);
       circular_trace_buffer = val;
       trace_debug ("Trace buffer is now %s",
                   circular_trace_buffer ? "circular" : "linear");
@@ -3461,6 +3522,16 @@ handle_tracepoint_general_set (char *packet)
       cmd_qtdpsrc (packet);
       return 1;
     }
+  else if (strncmp ("QTEnable:", packet, strlen ("QTEnable:")) == 0)
+    {
+      cmd_qtenable_disable (packet, 1);
+      return 1;
+    }
+  else if (strncmp ("QTDisable:", packet, strlen ("QTDisable:")) == 0)
+    {
+      cmd_qtenable_disable (packet, 0);
+      return 1;
+    }
   else if (strncmp ("QTDV:", packet, strlen ("QTDV:")) == 0)
     {
       cmd_qtdv (packet);
@@ -5340,6 +5411,9 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs)
   if (!tracing)
     return;
 
+  if (!tpoint->enabled)
+    return;
+
   ctx.base.type = fast_tracepoint;
   ctx.regs = regs;
   ctx.regcache_initted = 0;
@@ -6598,7 +6672,7 @@ ust_marker_to_static_tracepoint (const struct marker *mdata)
 
   for (tpoint = tracepoints; tpoint; tpoint = tpoint->next)
     {
-      if (!tpoint->enabled || tpoint->type != static_tracepoint)
+      if (tpoint->type != static_tracepoint)
        continue;
 
       if (tpoint->address == (uintptr_t) mdata->location)
@@ -6653,6 +6727,12 @@ gdb_probe (const struct marker *mdata, void *probe_private,
       return;
     }
 
+  if (!tpoint->enabled)
+    {
+      trace_debug ("gdb_probe: tracepoint disabled");
+      return;
+    }
+
   ctx.tpoint = tpoint;
 
   trace_debug ("gdb_probe: collecting marker: "
This page took 0.053701 seconds and 4 git commands to generate.