Implement -trace-find.
authorVladimir Prus <vladimir@codesourcery.com>
Tue, 23 Mar 2010 22:01:47 +0000 (22:01 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Tue, 23 Mar 2010 22:01:47 +0000 (22:01 +0000)
* mi/mi-cmds.c (mi_cmds): Register -trace-find.
* mi/mi-cmds.h (mi_cmd_trace_find): Declare.
* mi/mi-main.c (mi_cmd_trace_find): New.
* target.h (struct target_ops): Document to_trace_find.
* tracepoint.h (tfind_1): Declare.
* tracepoint.c (finish_tfind_command): Rename to...
(tfind_1): ...this.
* remote.c (remote_trace_find): Return -1 if target say
there's no frame.  Improve error diagnostics.

gdb/ChangeLog
gdb/mi/mi-cmds.c
gdb/mi/mi-cmds.h
gdb/mi/mi-main.c
gdb/remote.c
gdb/target.h
gdb/tracepoint.c
gdb/tracepoint.h

index 7f74fe3373161b49d158bee3643ff59ee3689d42..a50604d0fc18baec72cefc45b6cb67163b509e52 100644 (file)
@@ -1,3 +1,17 @@
+2010-03-24  Vladimir Prus  <vladimir@codesourcery.com>
+
+       Implement -trace-find.
+
+       * mi/mi-cmds.c (mi_cmds): Register -trace-find.
+       * mi/mi-cmds.h (mi_cmd_trace_find): Declare.
+       * mi/mi-main.c (mi_cmd_trace_find): New.
+       * target.h (struct target_ops): Document to_trace_find.
+       * tracepoint.h (tfind_1): Declare.
+       * tracepoint.c (finish_tfind_command): Rename to...
+       (tfind_1): ...this.
+       * remote.c (remote_trace_find): Return -1 if target say
+       there's no frame.  Improve error diagnostics.
+
 2010-03-24  Vladimir Prus  <vladimir@codesourcery.com>
 
        -trace-define-variable and -trace-list-variables.
index a07ee3b437251e70dfaac08bbc8ec1d07a950b90..f43069808c90cc7d5ab154812f6441ecbb5d0faf 100644 (file)
@@ -107,6 +107,7 @@ struct mi_cmd mi_cmds[] =
   { "thread-list-ids", { NULL, 0 }, mi_cmd_thread_list_ids},
   { "thread-select", { NULL, 0 }, mi_cmd_thread_select},
   { "trace-define-variable", { NULL, 0 }, mi_cmd_trace_define_variable },
+  { "trace-find", { NULL, 0 }, mi_cmd_trace_find },
   { "trace-list-variables", { NULL, 0 }, mi_cmd_trace_list_variables },
   { "trace-start", { NULL, 0 }, mi_cmd_trace_start },
   { "trace-status", { NULL, 0 }, mi_cmd_trace_status },
index dc2b2c6c74fccd94c75911f2eb1a3fe35100b4a3..32e0ec44d487832e731e59647b5fd075a78d5b16 100644 (file)
@@ -90,6 +90,7 @@ extern mi_cmd_argv_ftype mi_cmd_thread_info;
 extern mi_cmd_argv_ftype mi_cmd_thread_list_ids;
 extern mi_cmd_argv_ftype mi_cmd_thread_select;
 extern mi_cmd_argv_ftype mi_cmd_trace_define_variable;
+extern mi_cmd_argv_ftype mi_cmd_trace_find;
 extern mi_cmd_argv_ftype mi_cmd_trace_list_variables;
 extern mi_cmd_argv_ftype mi_cmd_trace_start;
 extern mi_cmd_argv_ftype mi_cmd_trace_status;
index 031c00608ec290dcd2e14183f27237bf3afddc17..b016436f6f510a159abbf5151845f247de416456 100644 (file)
@@ -2125,6 +2125,91 @@ mi_cmd_trace_list_variables (char *command, char **argv, int argc)
   tvariables_info_1 ();
 }
 
+void
+mi_cmd_trace_find (char *command, char **argv, int argc)
+{
+  char *mode;
+
+  if (argc == 0)
+    error (_("trace selection mode is required"));
+
+  mode = argv[0];
+
+  if (strcmp (mode, "none") == 0)
+    {
+      tfind_1 (tfind_number, -1, 0, 0, 0);
+      return;
+    }
+
+  if (current_trace_status ()->running)
+    error (_("May not look at trace frames while trace is running."));
+
+  if (strcmp (mode, "frame-number") == 0)
+    {
+      if (argc != 2)
+       error (_("frame number is required"));
+      tfind_1 (tfind_number, atoi (argv[1]), 0, 0, 0);
+    }
+  else if (strcmp (mode, "tracepoint-number") == 0)
+    {
+      if (argc != 2)
+       error (_("tracepoint number is required"));
+      tfind_1 (tfind_tp, atoi (argv[1]), 0, 0, 0);
+    }
+  else if (strcmp (mode, "pc") == 0)
+    {
+      if (argc != 2)
+       error (_("PC is required"));
+      tfind_1 (tfind_pc, 0, parse_and_eval_address (argv[1]), 0, 0);
+    }
+  else if (strcmp (mode, "pc-inside-range") == 0)
+    {
+      if (argc != 3)
+       error (_("Start and end PC are required"));
+      tfind_1 (tfind_range, 0, parse_and_eval_address (argv[1]),
+              parse_and_eval_address (argv[2]), 0);
+    }
+  else if (strcmp (mode, "pc-outside-range") == 0)
+    {
+      if (argc != 3)
+       error (_("Start and end PC are required"));
+      tfind_1 (tfind_outside, 0, parse_and_eval_address (argv[1]),
+              parse_and_eval_address (argv[2]), 0);
+    }
+  else if (strcmp (mode, "line") == 0)
+    {
+      struct symtabs_and_lines sals;
+      struct symtab_and_line sal;
+      static CORE_ADDR start_pc, end_pc;
+      struct cleanup *back_to;
+
+      if (argc != 2)
+       error (_("Line is required"));
+
+      sals = decode_line_spec (argv[1], 1);
+      back_to = make_cleanup (xfree, sals.sals);
+
+      sal = sals.sals[0];
+
+      if (sal.symtab == 0)
+       error (_("Could not find the specified line"));
+
+      if (sal.line > 0 && find_line_pc_range (sal, &start_pc, &end_pc))
+       tfind_1 (tfind_range, 0, start_pc, end_pc - 1, 0);
+      else
+       error (_("Could not find the specified line"));
+
+      do_cleanups (back_to);
+    }
+  else
+    error (_("Invalid mode '%s'"), mode);
+
+  if (has_stack_frames () || get_traceframe_number () >= 0)
+    {
+      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+    }
+}
+
 void
 mi_cmd_trace_start (char *command, char **argv, int argc)
 {
index d26f9a5b8bb68910ff7bacf2a579cd37313b279e..d041288d10736f4e396f152549d71d38d321e0cc 100644 (file)
@@ -9533,12 +9533,18 @@ remote_trace_find (enum trace_find_type type, int num,
     switch (*reply)
       {
       case 'F':
-       if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
-         error (_("Target failed to find requested trace frame."));
+       p = ++reply;
+       target_frameno = (int) strtol (p, &reply, 16);
+       if (reply == p)
+         error (_("Unable to parse trace frame number"));
+       if (target_frameno == -1)
+         return -1;
        break;
       case 'T':
-       if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
-         error (_("Target failed to find requested trace frame."));
+       p = ++reply;
+       target_tracept = (int) strtol (p, &reply, 16);
+       if (reply == p)
+         error (_("Unable to parse tracepoint number"));
        break;
       case 'O':                /* "OK"? */
        if (reply[1] == 'K' && reply[2] == '\0')
index 2b21f0f7346a8284ad7812d70280c3416340e199..46f5e7ed3de76f160163b4a01becda12d0c10172 100644 (file)
@@ -643,7 +643,8 @@ struct target_ops
    /* Ask the target to find a trace frame of the given type TYPE,
       using NUM, ADDR1, and ADDR2 as search parameters.  Returns the
       number of the trace frame, and also the tracepoint number at
-      TPP.  */
+      TPP.  If no trace frame matches, return -1. May throw if the
+      operation fails.  */
     int (*to_trace_find) (enum trace_find_type type, int num,
                          ULONGEST addr1, ULONGEST addr2, int *tpp);
 
index bf5cdba38ef53945850be02378932e8b2aad4b3f..02992604195552aef71d7a40b7919f50ac678d58 100644 (file)
@@ -1732,10 +1732,10 @@ disconnect_or_stop_tracing (int from_tty)
 }
 
 /* Worker function for the various flavors of the tfind command.  */
-static void
-finish_tfind_command (enum trace_find_type type, int num,
-                     ULONGEST addr1, ULONGEST addr2,
-                     int from_tty)
+void
+tfind_1 (enum trace_find_type type, int num,
+        ULONGEST addr1, ULONGEST addr2,
+        int from_tty)
 {
   int target_frameno = -1, target_tracept = -1;
   struct frame_id old_frame_id;
@@ -1802,6 +1802,30 @@ finish_tfind_command (enum trace_find_type type, int num,
   else
     set_traceframe_context (get_current_frame ());
 
+  if (traceframe_number >= 0)
+    {
+      /* Use different branches for MI and CLI to make CLI messages
+        i18n-eable.  */
+      if (ui_out_is_mi_like_p (uiout))
+       {
+         ui_out_field_string (uiout, "found", "1");
+         ui_out_field_int (uiout, "tracepoint", tracepoint_number);
+         ui_out_field_int (uiout, "traceframe", traceframe_number);
+       }
+      else
+       {
+         printf_unfiltered (_("Found trace frame %d, tracepoint %d\n"),
+                            traceframe_number, tracepoint_number);
+       }
+    }
+  else
+    {
+      if (ui_out_is_mi_like_p (uiout))
+       ui_out_field_string (uiout, "found", "0");
+      else
+       printf_unfiltered (_("No trace frame found"));
+    }
+
   /* If we're in nonstop mode and getting out of looking at trace
      frames, there won't be any current frame to go back to and
      display.  */
@@ -1875,7 +1899,7 @@ trace_find_command (char *args, int from_tty)
   if (frameno < -1)
     error (_("invalid input (%d is less than zero)"), frameno);
 
-  finish_tfind_command (tfind_number, frameno, 0, 0, from_tty);
+  tfind_1 (tfind_number, frameno, 0, 0, from_tty);
 }
 
 /* tfind end */
@@ -1914,7 +1938,7 @@ trace_find_pc_command (char *args, int from_tty)
   else
     pc = parse_and_eval_address (args);
 
-  finish_tfind_command (tfind_pc, 0, pc, 0, from_tty);
+  tfind_1 (tfind_pc, 0, pc, 0, from_tty);
 }
 
 /* tfind tracepoint command */
@@ -1944,7 +1968,7 @@ trace_find_tracepoint_command (char *args, int from_tty)
   if (tp)
     tdp = tp->number_on_target;
 
-  finish_tfind_command (tfind_tp, tdp, 0, 0, from_tty);
+  tfind_1 (tfind_tp, tdp, 0, 0, from_tty);
 }
 
 /* TFIND LINE command:
@@ -2032,9 +2056,9 @@ trace_find_line_command (char *args, int from_tty)
 
   /* Find within range of stated line.  */
   if (args && *args)
-    finish_tfind_command (tfind_range, 0, start_pc, end_pc - 1, from_tty);
+    tfind_1 (tfind_range, 0, start_pc, end_pc - 1, from_tty);
   else
-    finish_tfind_command (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
+    tfind_1 (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
   do_cleanups (old_chain);
 }
 
@@ -2069,7 +2093,7 @@ trace_find_range_command (char *args, int from_tty)
       stop = start + 1;        /* ??? */
     }
 
-  finish_tfind_command (tfind_range, 0, start, stop, from_tty);
+  tfind_1 (tfind_range, 0, start, stop, from_tty);
 }
 
 /* tfind outside command */
@@ -2103,7 +2127,7 @@ trace_find_outside_command (char *args, int from_tty)
       stop = start + 1;        /* ??? */
     }
 
-  finish_tfind_command (tfind_outside, 0, start, stop, from_tty);
+  tfind_1 (tfind_outside, 0, start, stop, from_tty);
 }
 
 /* info scope command: list the locals for a scope.  */
index ef4c8f0334814dac3e9a24300d162c37d5a3e303..b9555b784859d085e7d139b791f0cf37e038d949 100644 (file)
@@ -20,6 +20,9 @@
 #if !defined (TRACEPOINT_H)
 #define TRACEPOINT_H 1
 
+#include "breakpoint.h"
+#include "target.h"
+
 enum actionline_type
   {
     BADLINE = -1,
@@ -177,4 +180,8 @@ extern void trace_status_mi (int on_stop);
 
 extern void tvariables_info_1 (void);
 
+extern void tfind_1 (enum trace_find_type type, int num,
+                    ULONGEST addr1, ULONGEST addr2,
+                    int from_tty);
+
 #endif /* TRACEPOINT_H */