From: Stan Shebs Date: Thu, 31 Dec 2009 17:47:43 +0000 (+0000) Subject: Add new tracepoint action teval. X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=6da95a677b977e132bc936a73b2bb92844b14f32;p=deliverable%2Fbinutils-gdb.git 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. * gdb.texinfo (Tracepoint Actions): Describe teval. * gdb.trace/actions.exp: Test teval action. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4f538acc80..753fbb0cc0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,12 @@ 2009-12-31 Stan Shebs + 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_find_command): Error out if trace running. (trace_find_pc_command): Ditto. (trace_find_tracepoint_command): Ditto. diff --git a/gdb/NEWS b/gdb/NEWS index eb84ee7e9e..184c4e64c2 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -97,6 +97,10 @@ info tvariables 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 diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 7171423258..6c5bfe77f9 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2009-12-31 Stan Shebs + + * gdb.texinfo (Tracepoint Actions): Describe teval. + 2009-12-29 Stan Shebs * gdb.texinfo (Tracepoint Actions): Describe default-collect. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 39f0d67924..f7bc686e42 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -9626,6 +9626,15 @@ arguments separated by commas: the effect is the same. 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 diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 33aee0831c..10dc1d55eb 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-12-31 Stan Shebs + + * gdb.trace/actions.exp: Test teval action. + 2009-12-30 Thiago Jung Bauermann * gdb.base/watchpoint.exp (test_watchpoint_in_big_blob): New function. diff --git a/gdb/testsuite/gdb.trace/actions.exp b/gdb/testsuite/gdb.trace/actions.exp index bb7277f993..616a656f2f 100644 --- a/gdb/testsuite/gdb.trace/actions.exp +++ b/gdb/testsuite/gdb.trace/actions.exp @@ -212,3 +212,31 @@ gdb_test "set default-collect gdb_char_test, gdb_long_test - 100" \ 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" + diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 26a836d80c..fd7c161640 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -525,6 +525,12 @@ collect_pseudocommand (char *args, int from_tty) 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) @@ -761,6 +767,34 @@ validate_actionline (char **line, struct breakpoint *t) 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 */ @@ -1464,6 +1498,46 @@ encode_actions (struct breakpoint *t, char ***tdp_actions, } 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; @@ -2624,6 +2698,12 @@ Also accepts the following special arguments:\n\ $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\