[MI tracepoints 7/9] -trace-find

Vladimir Prus
2010-03-14T08:59:53Z

[-- Attachment #1: Type: Text/Plain, Size: 113 bytes --]

Yet another command. OK?

Thanks,

--
Vladimir Prus
CodeSourcery
vladimir@codesourcery.com
(650) 331-3385 x722

[-- Attachment #2: 7-trace-find.diff --]
[-- Type: text/x-patch, Size: 9848 bytes --]

commit 5b982e6f92c5cd39bbba8c9eb7f776d96c0c24a1
Author: Vladimir Prus <vladimir@codesourcery.com>
Date: Sat Mar 13 17:55:01 2010 +0300

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.

diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index a07ee3b..f430698 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -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 },
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index dc2b2c6..32e0ec4 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -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;
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 77ee026..8847ca3 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2133,6 +2133,91 @@ mi_cmd_trace_list_variables (char *command, char **argv, int argc)
}

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 (_("frame 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)
{
start_tracing ();
diff --git a/gdb/remote.c b/gdb/remote.c
index ed1dc20..cc1c3d1 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -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')
diff --git a/gdb/target.h b/gdb/target.h
index 7fd9bad..4da6aee 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -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. ay throw if the
+ operation fails. */
int (*to_trace_find) (enum trace_find_type type, int num,
ULONGEST addr1, ULONGEST addr2, int *tpp);

diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 353fe42..5ce8167 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -1686,10 +1686,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;
@@ -1756,6 +1756,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. */
@@ -1829,7 +1853,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 */
@@ -1868,7 +1892,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 */
@@ -1898,7 +1922,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:
@@ -1986,9 +2010,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);
}

@@ -2023,7 +2047,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 */
@@ -2057,7 +2081,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. */
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index d03f09a..40dc4e9 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -20,6 +20,9 @@
#if !defined (TRACEPOINT_H)
#define TRACEPOINT_H 1

+#include "breakpoint.h"
+#include "target.h"
+
enum actionline_type
{
BADLINE = -1,
@@ -165,4 +168,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 */