This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] Add teval tracepoint action
- From: Stan Shebs <stan at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 30 Dec 2009 18:40:33 -0800
- Subject: [PATCH] Add teval tracepoint action
The use of trace state variables in a tracepoint's action list presents
a problem; the only available action is "collect", which has the side
effect of saving the variable's value into the trace buffer. In some
cases this might be useful; in others, the trace buffer might fill up
with useless copies of variable values. So this patch introduces a new
action "teval" which has the same syntax as collect, but only evaluates
its expressions and does not put anything into the trace buffer.
(Tracepoint fans may remember that this was originally proposed as "do",
but that is ambiguous with "down", so I changed it to be "eval" - but
that reserves a term that we may want for general evaluation, so Tom
Tromey suggested "teval", analogously with other t-prefixed tracepoint
commands.)
Stan
2009-12-30 Stan Shebs <stan@codesourcery.com>
Add new tracepoint action teval.
* tracepoint.c (teval_pseudocommand): New function.
(validate_actionline): Add teval action case.
(encode_actions): Ditto.
(_initialize_tracepoint): Define teval pseudocommand.
* NEWS: Mention teval.
* tracepoint.c (trace_status_command): Add some status output.
* gdb.texinfo (Tracepoint Actions): Describe teval.
* gdb.trace/actions.exp: Test teval action.
Index: tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.c,v
retrieving revision 1.131
diff -p -r1.131 tracepoint.c
*** tracepoint.c 30 Dec 2009 22:32:03 -0000 1.131
--- tracepoint.c 31 Dec 2009 01:57:05 -0000
*************** collect_pseudocommand (char *args, int f
*** 525,530 ****
--- 525,536 ----
error (_("This command can only be used in a tracepoint actions list."));
}
+ static void
+ teval_pseudocommand (char *args, int from_tty)
+ {
+ error (_("This command can only be used in a tracepoint actions list."));
+ }
+
/* Enter a list of actions for a tracepoint. */
static void
trace_actions_command (char *args, int from_tty)
*************** validate_actionline (char **line, struct
*** 761,766 ****
--- 767,800 ----
while (p && *p++ == ',');
return GENERIC;
}
+ else if (cmd_cfunc_eq (c, teval_pseudocommand))
+ {
+ struct agent_expr *aexpr;
+
+ do
+ { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ while (isspace ((int) *p))
+ p++;
+
+ /* Only expressions are allowed for this action. */
+ exp = parse_exp_1 (&p, block_for_pc (t->loc->address), 1);
+ old_chain = make_cleanup (free_current_contents, &exp);
+
+ /* We have something to evaluate, make sure that the expr to
+ bytecode translator can handle it and that it's not too
+ long. */
+ aexpr = gen_eval_for_expr (t->loc->address, exp);
+ make_cleanup_free_agent_expr (aexpr);
+
+ if (aexpr->len > MAX_AGENT_EXPR_LEN)
+ error (_("expression too complicated, try simplifying"));
+
+ do_cleanups (old_chain);
+ }
+ while (p && *p++ == ',');
+ return GENERIC;
+ }
else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
{
char *steparg; /* in case warning is necessary */
*************** encode_actions (struct breakpoint *t, ch
*** 1464,1469 ****
--- 1498,1543 ----
}
while (action_exp && *action_exp++ == ',');
} /* if */
+ else if (cmd_cfunc_eq (cmd, teval_pseudocommand))
+ {
+ do
+ { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ while (isspace ((int) *action_exp))
+ action_exp++;
+
+ {
+ unsigned long addr, len;
+ struct cleanup *old_chain = NULL;
+ struct cleanup *old_chain1 = NULL;
+ struct agent_reqs areqs;
+
+ exp = parse_exp_1 (&action_exp,
+ block_for_pc (t->loc->address), 1);
+ old_chain = make_cleanup (free_current_contents, &exp);
+
+ aexpr = gen_eval_for_expr (t->loc->address, exp);
+ old_chain1 = make_cleanup_free_agent_expr (aexpr);
+
+ ax_reqs (aexpr, &areqs);
+ if (areqs.flaw != agent_flaw_none)
+ error (_("malformed expression"));
+
+ if (areqs.min_height < 0)
+ error (_("gdb: Internal error: expression has min height < 0"));
+ if (areqs.max_height > 20)
+ error (_("expression too complicated, try simplifying"));
+
+ discard_cleanups (old_chain1);
+ /* Even though we're not officially collecting, add
+ to the collect list anyway. */
+ add_aexpr (collect, aexpr);
+
+ do_cleanups (old_chain);
+ } /* do */
+ }
+ while (action_exp && *action_exp++ == ',');
+ } /* if */
else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
{
collect = &stepping_list;
*************** Also accepts the following special argum
*** 2606,2611 ****
--- 2680,2691 ----
$locals -- all variables local to the block/function scope.\n\
Note: this command can only be used in a tracepoint \"actions\" list."));
+ add_com ("teval", class_trace, teval_pseudocommand, _("\
+ Specify one or more expressions to be evaluated at a tracepoint.\n\
+ Accepts a comma-separated list of (one or more) expressions.\n\
+ The result of each evaluation will be discarded.\n\
+ Note: this command can only be used in a tracepoint \"actions\" list."));
+
add_com ("actions", class_trace, trace_actions_command, _("\
Specify the actions to be taken at a tracepoint.\n\
Tracepoint actions may include collecting of specified data, \n\
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.343
diff -p -r1.343 NEWS
*** NEWS 30 Dec 2009 16:11:06 -0000 1.343
--- NEWS 31 Dec 2009 01:57:05 -0000
*************** info tvariables
*** 97,102 ****
--- 97,106 ----
delete tvariable $NAME ...
Delete one or more trace state variables.
+ teval EXPR, ...
+ Evaluate the given expressions without collecting anything into the
+ trace buffer. (Valid in tracepoint actions only.)
+
* New options
set follow-exec-mode new|same
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.652
diff -p -r1.652 gdb.texinfo
*** doc/gdb.texinfo 30 Dec 2009 16:11:07 -0000 1.652
--- doc/gdb.texinfo 31 Dec 2009 01:57:06 -0000
*************** arguments separated by commas: the effec
*** 9626,9631 ****
--- 9626,9640 ----
The command @code{info scope} (@pxref{Symbols, info scope}) is
particularly useful for figuring out what data to collect.
+ @kindex teval @r{(tracepoints)}
+ @item teval @var{expr1}, @var{expr2}, @dots{}
+ Evaluate the given expressions when the tracepoint is hit. This
+ command accepts a comma-separated list of expressions. The results
+ are discarded, so this is mainly useful for assigning values to trace
+ state variables (@pxref{Trace State Variables}) without adding those
+ values to the trace buffer, as would be the case if the @code{collect}
+ action were used.
+
@kindex while-stepping @r{(tracepoints)}
@item while-stepping @var{n}
Perform @var{n} single-step traces after the tracepoint, collecting
Index: testsuite/gdb.trace/actions.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.trace/actions.exp,v
retrieving revision 1.13
diff -p -r1.13 actions.exp
*** testsuite/gdb.trace/actions.exp 30 Dec 2009 16:11:08 -0000 1.13
--- testsuite/gdb.trace/actions.exp 31 Dec 2009 01:57:06 -0000
*************** gdb_test "set default-collect gdb_char_t
*** 212,214 ****
--- 212,242 ----
gdb_test "show default-collect" \
"The list of expressions to collect by default is \"gdb_char_test, gdb_long_test - 100\"..*" \
"5.9b: show default-collect"
+
+ # 5.10 teval
+
+ gdb_test "tvariable \$tsv" \
+ "Trace state variable \\\$tsv created, with initial value 0." \
+ "Create a trace state variable"
+
+ gdb_trace_setactions "5.10a: set teval action for first tracepoint" \
+ "$trcpt1" \
+ "teval gdb_char_test" "^$"
+
+ gdb_trace_setactions "5.10a: set teval action for second tracepoint" \
+ "$trcpt2" \
+ "teval \$tsv += 1" "^$"
+
+ gdb_test "info tracepoints" \
+ "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+ \[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
+ \[\t \]+A\[\t \]+teval gdb_char_test.
+ \[\t \]+A\[\t \]+end.
+ \[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
+ \[\t \]+A\[\t \]+teval \\\$tsv \\\+= 1.
+ \[\t \]+A\[\t \]+end.
+ \[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
+ \[\t \]+A\[\t \]+collect gdb_long_test.
+ \[\t \]+A\[\t \]+end." \
+ "5.10a: verify teval actions set for two tracepoints"
+