aboutsummaryrefslogtreecommitdiff
path: root/gdb/tracepoint.c
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2010-03-23 21:32:28 +0000
committerVladimir Prus <vladimir@codesourcery.com>2010-03-23 21:32:28 +0000
commita7bdde9e633ffde58462e01bdfb0d1ee9a642d7c (patch)
tree21df3445afaf8f0d2a61166c724029025fbf834c /gdb/tracepoint.c
parent64e3cf3d4f121e456a09c3998c4aa6d739e61f8a (diff)
downloadfsf-binutils-gdb-a7bdde9e633ffde58462e01bdfb0d1ee9a642d7c.zip
fsf-binutils-gdb-a7bdde9e633ffde58462e01bdfb0d1ee9a642d7c.tar.gz
fsf-binutils-gdb-a7bdde9e633ffde58462e01bdfb0d1ee9a642d7c.tar.bz2
Unify actions and commands
* defs.h (read_command_lines, read_command_lines_1): New parameters validator and closure. * tracepoint.h (struct action_line): Remove. * breakpoint.h (struct breakpoint): Remove the 'actions' field. * defs.h (enum command_control_type): New value while_stepping_control. (struct command_line): Add comments. * breakpoint.c (breakoint_is_tracepoint): New. (breakpoint_set_commands): For tracepoints, verify the commands are permissible. (check_tracepoint_commands): New. (commands_command): Require that each new line is validated using check_tracepoint_command, if we set commands for a tracepoint. (create_tracepoint_from_upload): Likewise. (print_one_breakpoint_location): Remove the code to print actions specifically. (tracepoint_save_command): Relay to print_command_lines. * cli/cli-script.c (process_next_line): New parameters validator and closure. Handle 'while-stepping'. Call validator if not null. (read_command_lines, read_command_lines1): Likewise. (recurse_read_control_structure): New parameters validator and closure. Handle while_stepping_control. (print_command_lines): Handle while-stepping. (get_command_line, define_command, document_command): Adjust. * remote.c (remote_download_tracepoint): Adjust. * tracepoint.c (make_cleanup_free_actions, read_actions) (free_actions, do_free_actions_cleanup): Remove. (trace_actions_command): Use read_command_lines. (validate_actionline): Use error in one place. (encode_actions_1): New, extracted from... (encode_actions): ...this. Also use cleanups for exception safety. (trace_dump_command): Adjust. * mi/mi-cmd-break (mi_cmd_break_commands): Validate commands if it's tracepoint.
Diffstat (limited to 'gdb/tracepoint.c')
-rw-r--r--gdb/tracepoint.c313
1 files changed, 90 insertions, 223 deletions
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 8af3a9b..dc52ead 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -178,7 +178,6 @@ static void add_aexpr (struct collection_list *, struct agent_expr *);
static char *mem2hex (gdb_byte *, char *, int);
static void add_register (struct collection_list *collection,
unsigned int regno);
-static struct cleanup *make_cleanup_free_actions (struct breakpoint *t);
extern void send_disconnected_tracing_value (int value);
@@ -450,9 +449,6 @@ tvariables_info (char *args, int from_tty)
/* ACTIONS functions: */
-/* Prototypes for action-parsing utility commands */
-static void read_actions (struct breakpoint *);
-
/* The three functions:
collect_pseudocommand,
while_stepping_pseudocommand, and
@@ -491,139 +487,24 @@ static void
trace_actions_command (char *args, int from_tty)
{
struct breakpoint *t;
- char tmpbuf[128];
- char *end_msg = "End with a line saying just \"end\".";
+ struct command_line *l;
t = get_tracepoint_by_number (&args, 0, 1);
if (t)
{
- sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
- t->number);
-
- if (from_tty)
- {
- if (deprecated_readline_begin_hook)
- (*deprecated_readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
- else if (input_from_terminal_p ())
- printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
- }
+ char *tmpbuf =
+ xstrprintf ("Enter actions for tracepoint %d, one per line.",
+ t->number);
+ struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
- free_actions (t);
- t->step_count = 0; /* read_actions may set this */
- read_actions (t);
-
- if (deprecated_readline_end_hook)
- (*deprecated_readline_end_hook) ();
- /* tracepoints_changed () */
+ l = read_command_lines (tmpbuf, from_tty, 1, check_tracepoint_command, t);
+ do_cleanups (cleanups);
+ breakpoint_set_commands (t, l);
}
/* else just return */
}
/* worker function */
-static void
-read_actions (struct breakpoint *t)
-{
- char *line;
- char *prompt1 = "> ", *prompt2 = " > ";
- char *prompt = prompt1;
- enum actionline_type linetype;
- extern FILE *instream;
- struct action_line *next = NULL, *temp;
- struct cleanup *old_chain;
-
- /* Control-C quits instantly if typed while in this loop
- since it should not wait until the user types a newline. */
- immediate_quit++;
- /* FIXME: kettenis/20010823: Something is wrong here. In this file
- STOP_SIGNAL is never defined. So this code has been left out, at
- least for quite a while now. Replacing STOP_SIGNAL with SIGTSTP
- leads to compilation failures since the variable job_control
- isn't declared. Leave this alone for now. */
-#ifdef STOP_SIGNAL
- if (job_control)
- signal (STOP_SIGNAL, handle_stop_sig);
-#endif
- old_chain = make_cleanup_free_actions (t);
- while (1)
- {
- /* Make sure that all output has been output. Some machines may
- let you get away with leaving out some of the gdb_flush, but
- not all. */
- wrap_here ("");
- gdb_flush (gdb_stdout);
- gdb_flush (gdb_stderr);
-
- if (deprecated_readline_hook && instream == NULL)
- line = (*deprecated_readline_hook) (prompt);
- else if (instream == stdin && ISATTY (instream))
- {
- line = gdb_readline_wrapper (prompt);
- if (line && *line) /* add it to command history */
- add_history (line);
- }
- else
- line = gdb_readline (0);
-
- if (!line)
- {
- line = xstrdup ("end");
- printf_filtered ("end\n");
- }
-
- linetype = validate_actionline (&line, t);
- if (linetype == BADLINE)
- continue; /* already warned -- collect another line */
-
- temp = xmalloc (sizeof (struct action_line));
- temp->next = NULL;
- temp->action = line;
-
- if (next == NULL) /* first action for this tracepoint? */
- t->actions = next = temp;
- else
- {
- next->next = temp;
- next = temp;
- }
-
- if (linetype == STEPPING) /* begin "while-stepping" */
- {
- if (prompt == prompt2)
- {
- warning (_("Already processing 'while-stepping'"));
- continue;
- }
- else
- prompt = prompt2; /* change prompt for stepping actions */
- }
- else if (linetype == END)
- {
- if (prompt == prompt2)
- {
- prompt = prompt1; /* end of single-stepping actions */
- }
- else
- { /* end of actions */
- if (t->actions->next == NULL)
- {
- /* An "end" all by itself with no other actions
- means this tracepoint has no actions.
- Discard empty list. */
- free_actions (t);
- }
- break;
- }
- }
- }
-#ifdef STOP_SIGNAL
- if (job_control)
- signal (STOP_SIGNAL, SIG_DFL);
-#endif
- immediate_quit--;
- discard_cleanups (old_chain);
-}
-
-/* worker function */
enum actionline_type
validate_actionline (char **line, struct breakpoint *t)
{
@@ -772,8 +653,7 @@ validate_actionline (char **line, struct breakpoint *t)
if (*p == '\0' ||
(t->step_count = strtol (p, &p, 0)) == 0)
{
- warning (_("'%s': bad step-count; command ignored."), *line);
- return BADLINE;
+ error (_("'%s': bad step-count."), *line);
}
return STEPPING;
}
@@ -781,37 +661,8 @@ validate_actionline (char **line, struct breakpoint *t)
return END;
else
{
- warning (_("'%s' is not a supported tracepoint action."), *line);
- return BADLINE;
- }
-}
-
-/* worker function */
-void
-free_actions (struct breakpoint *t)
-{
- struct action_line *line, *next;
-
- for (line = t->actions; line; line = next)
- {
- next = line->next;
- if (line->action)
- xfree (line->action);
- xfree (line);
+ error (_("'%s' is not a supported tracepoint action."), *line);
}
- t->actions = NULL;
-}
-
-static void
-do_free_actions_cleanup (void *t)
-{
- free_actions (t);
-}
-
-static struct cleanup *
-make_cleanup_free_actions (struct breakpoint *t)
-{
- return make_cleanup (do_free_actions_cleanup, t);
}
enum {
@@ -1271,70 +1122,31 @@ stringify_collection_list (struct collection_list *list, char *string)
return *str_list;
}
-/* Render all actions into gdb protocol. */
-/*static*/ void
-encode_actions (struct breakpoint *t, struct bp_location *tloc,
- char ***tdp_actions, char ***stepping_actions)
+
+static void
+encode_actions_1 (struct command_line *action,
+ struct breakpoint *t,
+ struct bp_location *tloc,
+ int frame_reg,
+ LONGEST frame_offset,
+ struct collection_list *collect,
+ struct collection_list *stepping_list)
{
- static char tdp_buff[2048], step_buff[2048];
char *action_exp;
struct expression *exp = NULL;
- struct action_line *action;
+ struct command_line *actions;
int i;
struct value *tempval;
- struct collection_list *collect;
struct cmd_list_element *cmd;
struct agent_expr *aexpr;
- int frame_reg;
- LONGEST frame_offset;
- char *default_collect_line = NULL;
- struct action_line *default_collect_action = NULL;
-
- clear_collection_list (&tracepoint_list);
- clear_collection_list (&stepping_list);
- collect = &tracepoint_list;
-
- *tdp_actions = NULL;
- *stepping_actions = NULL;
-
- gdbarch_virtual_frame_pointer (t->gdbarch,
- tloc->address, &frame_reg, &frame_offset);
-
- action = t->actions;
-
- /* If there are default expressions to collect, make up a collect
- action and prepend to the action list to encode. Note that since
- validation is per-tracepoint (local var "xyz" might be valid for
- one tracepoint and not another, etc), we make up the action on
- the fly, and don't cache it. */
- if (*default_collect)
- {
- char *line;
- enum actionline_type linetype;
-
- default_collect_line = xmalloc (12 + strlen (default_collect));
- sprintf (default_collect_line, "collect %s", default_collect);
- line = default_collect_line;
- linetype = validate_actionline (&line, t);
- if (linetype != BADLINE)
- {
- default_collect_action = xmalloc (sizeof (struct action_line));
- default_collect_action->next = t->actions;
- default_collect_action->action = line;
- action = default_collect_action;
- }
- }
for (; action; action = action->next)
{
QUIT; /* allow user to bail out with ^C */
- action_exp = action->action;
+ action_exp = action->line;
while (isspace ((int) *action_exp))
action_exp++;
- if (*action_exp == '#') /* comment line */
- return;
-
cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
if (cmd == 0)
error (_("Bad action list item: %s"), action_exp);
@@ -1505,26 +1317,81 @@ encode_actions (struct breakpoint *t, struct bp_location *tloc,
} /* if */
else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
{
- collect = &stepping_list;
+ /* We check against nested while-stepping when setting
+ breakpoint action, so no way to run into nested
+ here. */
+ gdb_assert (stepping_list);
+
+ encode_actions_1 (action->body_list[0], t, tloc, frame_reg, frame_offset,
+ stepping_list, NULL);
}
- else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
+ else
+ error (_("Invalid tracepoint command '%s'"), action->line);
+ } /* for */
+}
+
+/* Render all actions into gdb protocol. */
+/*static*/ void
+encode_actions (struct breakpoint *t, struct bp_location *tloc,
+ char ***tdp_actions, char ***stepping_actions)
+{
+ static char tdp_buff[2048], step_buff[2048];
+ char *default_collect_line = NULL;
+ struct command_line *actions;
+ struct command_line *default_collect_action = NULL;
+ int frame_reg;
+ LONGEST frame_offset;
+ struct cleanup *back_to;
+
+ back_to = make_cleanup (null_cleanup, NULL);
+
+ clear_collection_list (&tracepoint_list);
+ clear_collection_list (&stepping_list);
+
+ *tdp_actions = NULL;
+ *stepping_actions = NULL;
+
+ gdbarch_virtual_frame_pointer (t->gdbarch,
+ t->loc->address, &frame_reg, &frame_offset);
+
+ actions = t->commands;
+
+ /* If there are default expressions to collect, make up a collect
+ action and prepend to the action list to encode. Note that since
+ validation is per-tracepoint (local var "xyz" might be valid for
+ one tracepoint and not another, etc), we make up the action on
+ the fly, and don't cache it. */
+ if (*default_collect)
+ {
+ char *line;
+ enum actionline_type linetype;
+
+ default_collect_line = xstrprintf ("collect %s", default_collect);
+ make_cleanup (xfree, default_collect_line);
+
+ line = default_collect_line;
+ linetype = validate_actionline (&line, t);
+ if (linetype != BADLINE)
{
- if (collect == &stepping_list) /* end stepping actions */
- collect = &tracepoint_list;
- else
- break; /* end tracepoint actions */
+ default_collect_action = xmalloc (sizeof (struct command_line));
+ make_cleanup (xfree, default_collect_action);
+ default_collect_action->next = t->commands;
+ default_collect_action->line = line;
+ actions = default_collect_action;
}
- } /* for */
+ }
+ encode_actions_1 (actions, t, tloc, frame_reg, frame_offset,
+ &tracepoint_list, &stepping_list);
+
memrange_sortmerge (&tracepoint_list);
memrange_sortmerge (&stepping_list);
- *tdp_actions = stringify_collection_list (&tracepoint_list,
+ *tdp_actions = stringify_collection_list (&tracepoint_list,
tdp_buff);
- *stepping_actions = stringify_collection_list (&stepping_list,
+ *stepping_actions = stringify_collection_list (&stepping_list,
step_buff);
- xfree (default_collect_line);
- xfree (default_collect_action);
+ do_cleanups (back_to);
}
static void
@@ -2276,7 +2143,7 @@ trace_dump_command (char *args, int from_tty)
struct regcache *regcache;
struct gdbarch *gdbarch;
struct breakpoint *t;
- struct action_line *action;
+ struct command_line *action;
char *action_exp, *next_comma;
struct cleanup *old_cleanups;
int stepping_actions = 0;
@@ -2316,12 +2183,12 @@ trace_dump_command (char *args, int from_tty)
if (loc->address == regcache_read_pc (regcache))
stepping_frame = 0;
- for (action = t->actions; action; action = action->next)
+ for (action = t->commands; action; action = action->next)
{
struct cmd_list_element *cmd;
QUIT; /* allow user to bail out with ^C */
- action_exp = action->action;
+ action_exp = action->line;
while (isspace ((int) *action_exp))
action_exp++;