From f197e0f1b1c70895aae1395b96d780379ec695ab Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Tue, 23 Mar 2010 22:01:47 +0000 Subject: [PATCH] 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. --- gdb/ChangeLog | 14 ++++++++ gdb/mi/mi-cmds.c | 1 + gdb/mi/mi-cmds.h | 1 + gdb/mi/mi-main.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/remote.c | 14 +++++--- gdb/target.h | 3 +- gdb/tracepoint.c | 46 +++++++++++++++++++------- gdb/tracepoint.h | 7 ++++ 8 files changed, 155 insertions(+), 16 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7f74fe3373..a50604d0fc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2010-03-24 Vladimir Prus + + 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 -trace-define-variable and -trace-list-variables. diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index a07ee3b437..f43069808c 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 dc2b2c6c74..32e0ec44d4 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 031c00608e..b016436f6f 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -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) { diff --git a/gdb/remote.c b/gdb/remote.c index d26f9a5b8b..d041288d10 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 2b21f0f734..46f5e7ed3d 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. May 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 bf5cdba38e..0299260419 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -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. */ diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index ef4c8f0334..b9555b7848 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, @@ -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 */ -- 2.34.1