Index: ax-gdb.c =================================================================== RCS file: /cvs/src/src/gdb/ax-gdb.c,v retrieving revision 1.53 diff -p -r1.53 ax-gdb.c *** ax-gdb.c 14 Jul 2009 21:40:30 -0000 1.53 --- ax-gdb.c 15 Dec 2009 13:28:33 -0000 *************** *** 35,40 **** --- 35,41 ---- #include "regcache.h" #include "user-regs.h" #include "language.h" + #include "tracepoint.h" /* To make sense of this file, you should read doc/agentexpr.texi. Then look at the types and enums in ax-gdb.h. For the code itself, *************** gen_expr (struct expression *exp, union *** 1592,1597 **** --- 1593,1620 ---- } break; + case BINOP_ASSIGN: + (*pc)++; + if ((*pc)[0].opcode == OP_INTERNALVAR) + { + char *name = internalvar_name ((*pc)[1].internalvar); + struct trace_state_variable *tsv; + (*pc) += 3; + gen_expr (exp, pc, ax, value); + tsv = find_trace_state_variable (name); + if (tsv) + { + ax_tsv (ax, aop_setv, tsv->number); + if (trace_kludge) + ax_tsv (ax, aop_tracev, tsv->number); + } + else + error (_("$%s is not a trace state variable, may not assign to it"), name); + } + else + error (_("May only assign to trace state variables")); + break; + /* Note that we need to be a little subtle about generating code for comma. In C, we can do some optimizations here because we know the left operand is only being evaluated for effect. *************** gen_expr (struct expression *exp, union *** 1643,1649 **** break; case OP_INTERNALVAR: ! error (_("GDB agent expressions cannot use convenience variables.")); /* Weirdo operator: see comments for gen_repeat for details. */ case BINOP_REPEAT: --- 1666,1689 ---- break; case OP_INTERNALVAR: ! { ! const char *name = internalvar_name ((*pc)[1].internalvar); ! struct trace_state_variable *tsv; ! (*pc) += 3; ! tsv = find_trace_state_variable (name); ! if (tsv) ! { ! ax_tsv (ax, aop_getv, tsv->number); ! if (trace_kludge) ! ax_tsv (ax, aop_tracev, tsv->number); ! /* Trace state variables are always 64-bit integers. */ ! value->kind = axs_rvalue; ! value->type = builtin_type (exp->gdbarch)->builtin_long_long; ! } ! else ! error (_("$%s is not a trace state variable; GDB agent expressions cannot use convenience variables."), name); ! } ! break; /* Weirdo operator: see comments for gen_repeat for details. */ case BINOP_REPEAT: Index: ax-general.c =================================================================== RCS file: /cvs/src/src/gdb/ax-general.c,v retrieving revision 1.15 diff -p -r1.15 ax-general.c *** ax-general.c 3 Jan 2009 05:57:50 -0000 1.15 --- ax-general.c 15 Dec 2009 13:28:33 -0000 *************** ax_reg (struct agent_expr *x, int reg) *** 272,277 **** --- 272,293 ---- x->buf[x->len + 2] = (reg) & 0xff; x->len += 3; } + + /* Assemble code to operate on a trace state variable. */ + + void + ax_tsv (struct agent_expr *x, enum agent_op op, int num) + { + /* Make sure the tsv number is in range. */ + if (num < 0 || num > 0xffff) + error (_("GDB bug: ax-general.c (ax_tsv): variable number out of range")); + + grow_expr (x, 3); + x->buf[x->len] = op; + x->buf[x->len + 1] = (num >> 8) & 0xff; + x->buf[x->len + 2] = (num) & 0xff; + x->len += 3; + } *************** struct aop_map aop_map[] = *** 324,332 **** {"pop", 0, 0, 1, 0}, /* 0x29 */ {"zero_ext", 1, 0, 1, 1}, /* 0x2a */ {"swap", 0, 0, 2, 2}, /* 0x2b */ ! {0, 0, 0, 0, 0}, /* 0x2c */ ! {0, 0, 0, 0, 0}, /* 0x2d */ ! {0, 0, 0, 0, 0}, /* 0x2e */ {0, 0, 0, 0, 0}, /* 0x2f */ {"trace16", 2, 0, 1, 1}, /* 0x30 */ }; --- 340,348 ---- {"pop", 0, 0, 1, 0}, /* 0x29 */ {"zero_ext", 1, 0, 1, 1}, /* 0x2a */ {"swap", 0, 0, 2, 2}, /* 0x2b */ ! {"getv", 2, 0, 0, 1}, /* 0x2c */ ! {"setv", 2, 0, 0, 1}, /* 0x2d */ ! {"tracev", 2, 0, 0, 1}, /* 0x2e */ {0, 0, 0, 0, 0}, /* 0x2f */ {"trace16", 2, 0, 1, 1}, /* 0x30 */ }; Index: ax.h =================================================================== RCS file: /cvs/src/src/gdb/ax.h,v retrieving revision 1.10 diff -p -r1.10 ax.h *** ax.h 3 Jan 2009 05:57:50 -0000 1.10 --- ax.h 15 Dec 2009 13:28:33 -0000 *************** enum agent_op *** 131,136 **** --- 131,139 ---- aop_pop = 0x29, aop_zero_ext = 0x2a, aop_swap = 0x2b, + aop_getv = 0x2c, + aop_setv = 0x2d, + aop_tracev = 0x2e, aop_trace16 = 0x30, aop_last }; *************** extern void ax_const_d (struct agent_exp *** 182,187 **** --- 185,193 ---- /* Assemble code to push the value of register number REG on the stack. */ extern void ax_reg (struct agent_expr *EXPR, int REG); + + /* Assemble code to operate on a trace state variable. */ + extern void ax_tsv (struct agent_expr *expr, enum agent_op op, int num); /* Functions for printing out expressions, and otherwise debugging Index: tracepoint.c =================================================================== RCS file: /cvs/src/src/gdb/tracepoint.c,v retrieving revision 1.126 diff -p -r1.126 tracepoint.c *** tracepoint.c 14 Jul 2009 21:40:30 -0000 1.126 --- tracepoint.c 15 Dec 2009 13:28:33 -0000 *************** *** 34,39 **** --- 34,40 ---- #include "tracepoint.h" #include "remote.h" extern int remote_supports_cond_tracepoints (void); + extern char *unpack_varlen_hex (char *buff, ULONGEST *result); #include "linespec.h" #include "regcache.h" #include "completer.h" *************** extern void output_command (char *, int) *** 107,112 **** --- 108,123 ---- /* ======= Important global variables: ======= */ + /* The list of all trace state variables. We don't retain pointers to + any of these for any reason - API is by name or number only - so it + works to have a vector of objects. */ + + VEC(tsv_s) *tvariables; + + /* The next integer to assign to a variable. */ + + int next_tsv_number = 1; + /* Number of last traceframe collected. */ static int traceframe_number; *************** static struct symtab_and_line traceframe *** 122,127 **** --- 133,141 ---- /* Tracing command lists */ static struct cmd_list_element *tfindlist; + static char *target_buf; + static long target_buf_size; + /* ======= Important command functions: ======= */ static void trace_actions_command (char *, int); static void trace_start_command (char *, int); *************** set_traceframe_context (struct frame_inf *** 270,275 **** --- 284,483 ---- traceframe_sal.symtab->filename); } + /* Create a new trace state variable with the given name. */ + + struct trace_state_variable * + create_trace_state_variable (const char *name) + { + struct trace_state_variable tsv; + + memset (&tsv, 0, sizeof (tsv)); + tsv.name = name; + tsv.number = next_tsv_number++; + return VEC_safe_push (tsv_s, tvariables, &tsv); + } + + /* Look for a trace state variable of the given name. */ + + struct trace_state_variable * + find_trace_state_variable (const char *name) + { + struct trace_state_variable *tsv; + int ix; + + for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) + if (strcmp (name, tsv->name) == 0) + return tsv; + + return NULL; + } + + void + delete_trace_state_variable (const char *name) + { + struct trace_state_variable *tsv; + int ix; + + /* Be relaxed about the special character. */ + if (*name == '$') + ++name; + + for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) + if (strcmp (name, tsv->name) == 0) + { + VEC_unordered_remove (tsv_s, tvariables, ix); + return; + } + + warning (_("No trace variable named \"$%s\", not deleting"), name); + } + + /* The 'tvariable' command collects a name and optional expression to + evaluate into an initial value. */ + + void + trace_variable_command (char *args, int from_tty) + { + struct expression *expr; + struct cleanup *old_chain; + struct internalvar *intvar = NULL; + LONGEST initval = 0; + struct trace_state_variable *tsv; + + if (!args || !*args) + error_no_arg (_("trace state variable name")); + + /* All the possible valid arguments are expressions. */ + expr = parse_expression (args); + old_chain = make_cleanup (free_current_contents, &expr); + + if (expr->nelts == 0) + error (_("No expression?")); + + /* Only allow two syntaxes; "$name" and "$name=value". */ + if (expr->elts[0].opcode == OP_INTERNALVAR) + { + intvar = expr->elts[1].internalvar; + } + else if (expr->elts[0].opcode == BINOP_ASSIGN + && expr->elts[1].opcode == OP_INTERNALVAR) + { + intvar = expr->elts[2].internalvar; + initval = value_as_long (evaluate_subexpression_type (expr, 4)); + } + else + error (_("Syntax must be $NAME [ = EXPR ]")); + + if (!intvar) + error (_("No name given")); + + if (strlen (internalvar_name (intvar)) <= 0) + error (_("Must supply a non-empty variable name")); + + /* If the variable already exists, just change its initial value. */ + tsv = find_trace_state_variable (internalvar_name (intvar)); + if (tsv) + { + tsv->initial_value = initval; + printf_filtered (_("Trace state variable $%s now has initial value %s.\n"), + tsv->name, plongest (tsv->initial_value)); + return; + } + + /* Create a new variable. */ + tsv = create_trace_state_variable (internalvar_name (intvar)); + tsv->initial_value = initval; + + printf_filtered (_("Trace state variable $%s created, with initial value %s.\n"), + tsv->name, plongest (tsv->initial_value)); + + do_cleanups (old_chain); + } + + void + delete_trace_variable_command (char *args, int from_tty) + { + int i, ix; + char **argv; + struct cleanup *back_to; + struct trace_state_variable *tsv; + + if (args == NULL) + { + if (query (_("Delete all trace state variables? "))) + VEC_free (tsv_s, tvariables); + dont_repeat (); + return; + } + + argv = gdb_buildargv (args); + back_to = make_cleanup_freeargv (argv); + + for (i = 0; argv[i] != NULL; i++) + { + delete_trace_state_variable (argv[i]); + } + + do_cleanups (back_to); + + dont_repeat (); + } + + /* List all the trace state variables. */ + + static void + tvariables_info (char *args, int from_tty) + { + struct trace_state_variable *tsv; + int ix; + char *reply; + ULONGEST tval; + + if (target_is_remote ()) + { + char buf[20]; + + for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) + { + /* We don't know anything about the value until we get a + valid packet. */ + tsv->value_known = 0; + sprintf (buf, "qTV:%x", tsv->number); + putpkt (buf); + reply = remote_get_noisy_reply (&target_buf, &target_buf_size); + if (reply && *reply) + { + if (*reply == 'V') + { + unpack_varlen_hex (reply + 1, &tval); + tsv->value = (LONGEST) tval; + tsv->value_known = 1; + } + /* FIXME say anything about oddball replies? */ + } + } + } + + printf_filtered (_("Name\t\t Initial\tCurrent\n")); + + for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) + { + printf_filtered ("$%s", tsv->name); + print_spaces_filtered (17 - strlen (tsv->name), gdb_stdout); + printf_filtered ("%s ", plongest (tsv->initial_value)); + print_spaces_filtered (11 - strlen (plongest (tsv->initial_value)), gdb_stdout); + if (tsv->value_known) + printf_filtered (" %s", plongest (tsv->value)); + else if (trace_running_p || traceframe_number >= 0) + /* The value is/was defined, but we don't have it. */ + printf_filtered (" "); + else + /* It is not meaningful to ask about the value. */ + printf_filtered (" "); + printf_filtered ("\n"); + } + } + /* ACTIONS functions: */ /* Prototypes for action-parsing utility commands */ *************** add_aexpr (struct collection_list *colle *** 1204,1212 **** collect->next_aexpr_elt++; } - static char *target_buf; - static long target_buf_size; - /* Set "transparent" memory ranges Allow trace mechanism to treat text-like sections --- 1412,1417 ---- *************** void download_tracepoint (struct breakpo *** 1262,1270 **** --- 1467,1477 ---- static void trace_start_command (char *args, int from_tty) { + char buf[2048]; VEC(breakpoint_p) *tp_vec = NULL; int ix; struct breakpoint *t; + struct trace_state_variable *tsv; dont_repeat (); /* Like "run", dangerous to repeat accidentally. */ *************** trace_start_command (char *args, int fro *** 1282,1287 **** --- 1489,1507 ---- } VEC_free (breakpoint_p, tp_vec); + /* Init any trace state variables that start with nonzero values. */ + + for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) + { + if (tsv->initial_value != 0) + { + sprintf (buf, "QTDV:%x:%s", + tsv->number, phex ((ULONGEST) tsv->initial_value, 8)); + putpkt (buf); + remote_get_noisy_reply (&target_buf, &target_buf_size); + } + } + /* Tell target to treat text-like sections as transparent. */ remote_set_transparent_ranges (); /* Now insert traps and begin collecting data. */ *************** _initialize_tracepoint (void) *** 2185,2190 **** --- 2405,2422 ---- add_com ("tdump", class_trace, trace_dump_command, _("Print everything collected at the current tracepoint.")); + add_com ("tvariable", class_trace, trace_variable_command,_("\ + Define a trace state variable.")); + + add_cmd ("tvariable", class_trace, delete_trace_variable_command, _("\ + Delete one or more trace state variables.\n\ + Arguments are the names of the variables to delete.\n\ + If no arguments are supplied, delete all variables."), &deletelist); + + add_info ("tvariables", tvariables_info, _("\ + Status of trace state variables and their values.\n\ + ")); + add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\ Select a trace frame;\n\ No argument means forward by one frame; '-' means backward by one frame."), Index: tracepoint.h =================================================================== RCS file: /cvs/src/src/gdb/tracepoint.h,v retrieving revision 1.15 diff -p -r1.15 tracepoint.h *** tracepoint.h 31 Mar 2009 05:08:32 -0000 1.15 --- tracepoint.h 15 Dec 2009 13:28:33 -0000 *************** enum actionline_type *** 35,40 **** --- 35,71 ---- STEPPING = 2 }; + /* A trace state variable is a value managed by a target being + traced. A trace state variable (or tsv for short) can be accessed + and assigned to by tracepoint actions and conditionals, but is not + part of the program being traced, and it doesn't have to be + collected. Effectively the variables are scratch space for + tracepoints. */ + + struct trace_state_variable + { + /* The variable's name. The user has to prefix with a dollar sign, + but we don't store that internally. */ + const char *name; + + /* An id number assigned by GDB, and transmitted to targets. */ + int number; + + /* The initial value of a variable is a 64-bit signed integer. */ + LONGEST initial_value; + + /* 1 if the value is known, else 0. The value is known during a + trace run, or in tfind mode if the variable was collected into + the current trace frame. */ + int value_known; + + /* The value of a variable is a 64-bit signed integer. */ + LONGEST value; + }; + + typedef struct trace_state_variable tsv_s; + DEF_VEC_O(tsv_s); + extern unsigned long trace_running_p; /* A hook used to notify the UI of tracepoint operations. */ *************** enum actionline_type validate_actionline *** 49,52 **** --- 80,85 ---- extern void end_actions_pseudocommand (char *args, int from_tty); extern void while_stepping_pseudocommand (char *args, int from_tty); + extern struct trace_state_variable *find_trace_state_variable (const char *name); + #endif /* TRACEPOINT_H */ Index: doc/agentexpr.texi =================================================================== RCS file: /cvs/src/src/gdb/doc/agentexpr.texi,v retrieving revision 1.9 diff -p -r1.9 agentexpr.texi *** doc/agentexpr.texi 11 Nov 2009 15:08:50 -0000 1.9 --- doc/agentexpr.texi 15 Dec 2009 13:28:33 -0000 *************** alignment within the bytecode stream; th *** 440,445 **** --- 440,463 ---- 16-bit on an unaligned address raises an exception, you should fetch the register number one byte at a time. + @item @code{getv} (0x2c) @var{n}: @result{} @var{v} + Push the value of trace state variable number @var{n}, without sign + extension. + + The variable number @var{n} is encoded as a 16-bit unsigned integer + immediately following the @code{getv} bytecode. It is always stored most + significant byte first, regardless of the target's normal endianness. + The variable number is not guaranteed to fall at any particular + alignment within the bytecode stream; thus, on machines where fetching a + 16-bit on an unaligned address raises an exception, you should fetch the + register number one byte at a time. + + @item @code{setv} (0x2d) @var{n}: @result{} @var{v} + Set trace state variable number @var{n} to the value found on the top + of the stack. The stack is unchanged, so that the value is readily + available if the assignment is part of a larger expression. The + handling of @var{n} is as described for @code{getv}. + @item @code{trace} (0x0c): @var{addr} @var{size} @result{} Record the contents of the @var{size} bytes at @var{addr} in a trace buffer, for later retrieval by GDB. *************** Identical to trace_quick, except that @v *** 457,462 **** --- 475,484 ---- unsigned integer, not a single byte. This should probably have been named @code{trace_quick16}, for consistency. + @item @code{tracev} (0x2e) @var{n}: @result{} @var{a} + Record the value of trace state variable number @var{n} in the trace + buffer. The handling of @var{n} is as described for @code{getv}. + @item @code{end} (0x27): @result{} Stop executing bytecode; the result should be the top element of the stack. If the purpose of the expression was to compute an lvalue or a Index: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.648 diff -p -r1.648 gdb.texinfo *** doc/gdb.texinfo 8 Dec 2009 14:06:02 -0000 1.648 --- doc/gdb.texinfo 15 Dec 2009 13:28:34 -0000 *************** conditions and actions. *** 9331,9336 **** --- 9331,9337 ---- * Enable and Disable Tracepoints:: * Tracepoint Passcounts:: * Tracepoint Conditions:: + * Trace State Variables:: * Tracepoint Actions:: * Listing Tracepoints:: * Starting and Stopping Trace Experiments:: *************** search through. *** 9497,9502 **** --- 9498,9550 ---- (@value{GDBP}) @kbd{trace normal_operation if errcode > 0} @end smallexample + @node Trace State Variables + @subsection Trace State Variables + + A @dfn{trace state variable} is a special type of variable that is + created and managed by target-side code. The syntax is the same as + that for GDB's convenience variables (a string prefixed with ``$''), + but they are stored on the target. They must be created explicitly, + using a @code{tvariable} command. They are always 64-bit signed + integers, and always updated atomically. + + Trace state variables are remembered by @value{GDBN}, and downloaded + to the target along with tracepoint information when the trace + experiment starts. There are no intrinsic limits on the number of + trace state variables, beyond memory limitations of the target. + + Although trace state variables are managed by the target, you can use + them in print commands and expressions as if they were convenience + variables; @value{GDBN} will get the current value from the target + while the trace experiment is running. Trace state variables share + the same namespace as other ``$'' variables, which means that you + cannot have trace state variables with names like @code{$23} or + @code{$pc}, nor can you have a trace state variable and a convenience + variable with the same name. + + @table @code + + @item tvariable $@var{name} [ = @var{expression} ] + @kindex tvariable + @cindex trace state variable + The @code{tvariable} command creates a new trace state variable named + @code{$}@var{name}, and optionally gives it an initial value of + @var{expression}. @var{expression} is evaluated when this command is + entered; the result will be converted to an integer if possible, + otherwise @value{GDBN} will report an error. A second @code{tvariable} + command with the same name assigns a new value to the variable. The + default initial value is 0. + + @item info tvariables + @kindex tvariables + List all the trace state variables along with their initial values. + + @item delete tvariable @r{[} $@var{name} @dots{} @r{]} + Delete the given trace state variables, or all of them if no arguments + are specified. + + @end table + @node Tracepoint Actions @subsection Tracepoint Action Lists *************** use @code{output} instead. *** 9929,9935 **** Here's a simple example of using these convenience variables for stepping through all the trace snapshots and printing some of their ! data. @smallexample (@value{GDBP}) @b{tfind start} --- 9977,9984 ---- Here's a simple example of using these convenience variables for stepping through all the trace snapshots and printing some of their ! data. Note that these are not the same as trace state variables, ! which are managed by the target. @smallexample (@value{GDBP}) @b{tfind start} *************** The packet was understood and carried ou *** 29971,29976 **** --- 30020,30033 ---- The packet was not recognized. @end table + @item QTDV:@var{n}:@var{value} + Create a new trace state variable, number @var{n}, with an initial + value of @var{value}, which is a 64-bit signed integer. Both @var{n} + and @var{value} are encoded as hexadecimal values. @value{GDBN} has + the option of not using this packet for initial values of zero; the + target should simply create the trace state variables as they are + mentioned in expressions. + @item QTFrame:@var{n} Select the @var{n}'th tracepoint frame from the buffer, and use the register and memory contents recorded there to answer subsequent *************** There is no trace experiment running. *** 30044,30051 **** --- 30101,30125 ---- There is a trace experiment running. @end table + @item qTV:@var{var} + Ask the stub for the value of the trace state variable number @var{var}. + + Replies: + @table @samp + @item V@var{value} + The value of the variable is @var{value}. This will be the current + value of the variable if the user is examining a running target, or a + saved value if the variable was collected in the trace frame that the + user is looking at. Note that multiple requests may result in different + reply values, such as for variables like @code{$trace_timestamp} that are + computed by the target program. + @item U + The value of the variable is unknown. This would occur, for example, + if the user is examining a trace frame in which the requested variable + was not collected. @end table + @end table @node Host I/O Packets @section Host I/O Packets Index: testsuite/gdb.base/completion.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/completion.exp,v retrieving revision 1.39 diff -p -r1.39 completion.exp *** testsuite/gdb.base/completion.exp 13 Jul 2009 19:24:18 -0000 1.39 --- testsuite/gdb.base/completion.exp 15 Dec 2009 13:28:34 -0000 *************** gdb_expect { *** 211,217 **** -re "^info t foo\\\x07$"\ { send_gdb "\n" gdb_expect { ! -re "Ambiguous info command \"t foo\": target, tasks, terminal, threads, tp, tracepoints, types\\..*$gdb_prompt $"\ { pass "complete 'info t foo'"} -re ".*$gdb_prompt $" { fail "complete 'info t foo'"} timeout {fail "(timeout) complete 'info t foo'"} --- 211,217 ---- -re "^info t foo\\\x07$"\ { send_gdb "\n" gdb_expect { ! -re "Ambiguous info command \"t foo\": target, tasks, terminal, threads, tp, tracepoints, tvariables, types\\..*$gdb_prompt $"\ { pass "complete 'info t foo'"} -re ".*$gdb_prompt $" { fail "complete 'info t foo'"} timeout {fail "(timeout) complete 'info t foo'"} *************** gdb_expect { *** 227,233 **** -re "^info t\\\x07$"\ { send_gdb "\n" gdb_expect { ! -re "Ambiguous info command \"t\": target, tasks, terminal, threads, tp, tracepoints, types\\.. *$gdb_prompt $"\ { pass "complete 'info t'"} -re ".*$gdb_prompt $" { fail "complete 'info t'"} --- 227,233 ---- -re "^info t\\\x07$"\ { send_gdb "\n" gdb_expect { ! -re "Ambiguous info command \"t\": target, tasks, terminal, threads, tp, tracepoints, tvariables, types\\.. *$gdb_prompt $"\ { pass "complete 'info t'"} -re ".*$gdb_prompt $" { fail "complete 'info t'"} *************** gdb_expect { *** 245,251 **** -re "^info t \\\x07$"\ { send_gdb "\n" gdb_expect { ! -re "Ambiguous info command \"t \": target, tasks, terminal, threads, tp, tracepoints, types\\.. *$gdb_prompt $"\ { pass "complete 'info t '"} -re ".*$gdb_prompt $" { fail "complete 'info t '"} --- 245,251 ---- -re "^info t \\\x07$"\ { send_gdb "\n" gdb_expect { ! -re "Ambiguous info command \"t \": target, tasks, terminal, threads, tp, tracepoints, tvariables, types\\.. *$gdb_prompt $"\ { pass "complete 'info t '"} -re ".*$gdb_prompt $" { fail "complete 'info t '"} Index: testsuite/gdb.trace/tsv.exp =================================================================== RCS file: testsuite/gdb.trace/tsv.exp diff -N testsuite/gdb.trace/tsv.exp *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/gdb.trace/tsv.exp 15 Dec 2009 13:28:34 -0000 *************** *** 0 **** --- 1,107 ---- + # Copyright 2009 Free Software Foundation, Inc. + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + + load_lib "trace-support.exp"; + + if $tracelevel then { + strace $tracelevel + } + + set prms_id 0 + set bug_id 0 + + gdb_exit + gdb_start + set testfile "actions" + set srcfile ${testfile}.c + set binfile $objdir/$subdir/tsv + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ + executable {debug nowarnings}] != "" } { + untested tracecmd.exp + return -1 + } + gdb_reinitialize_dir $srcdir/$subdir + + # If testing on a remote host, download the source file. + # remote_download host $srcdir/$subdir/$srcfile + + gdb_file_cmd $binfile + + gdb_test "tvariable \$tvar1" \ + "Trace state variable \\\$tvar1 created, with initial value 0." \ + "Create a trace state variable" + + gdb_test "tvariable \$tvar2 = 45" \ + "Trace state variable \\\$tvar2 created, with initial value 45." \ + "Create a trace state variable with initial value" + + gdb_test "tvariable \$tvar2 = -92" \ + "Trace state variable \\\$tvar2 now has initial value -92." \ + "Change initial value of a trace state variable" + + gdb_test "tvariable \$tvar3 = 2 + 3" \ + "Trace state variable \\\$tvar3 created, with initial value 5." \ + "Create a trace state variable with expression" + + gdb_test "tvariable \$tvar3 = 1234567000000" \ + "Trace state variable \\\$tvar3 now has initial value 1234567000000." \ + "Init trace state variable to a 64-bit value" + + gdb_test "tvariable main" \ + "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \ + "tvariable syntax error, bad name" + + gdb_test "tvariable \$tvar1 - 93" \ + "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \ + "tvariable syntax error, not an assignment" + + gdb_test "info tvariables" \ + "Name\[\t \]+Initial\[\t \]+Current.* + \\\$tvar1\[\t \]+0\[\t \]+.* + \\\$tvar2\[\t \]+-92\[\t \]+.* + \\\$tvar3\[\t \]+1234567000000\[\t \]+.*.*" \ + "List tvariables" + + gdb_test "delete tvariable \$tvar2" \ + "" \ + "delete trace state variable" + + gdb_test "info tvariables" \ + "Name\[\t \]+Initial\[\t \]+Current.* + \\\$tvar1\[\t \]+0\[\t \]+.* + \\\$tvar3\[\t \]+1234567000000\[\t \]+.*.*" \ + "List tvariables after deletion" + + send_gdb "delete tvariable\n" + gdb_expect 30 { + -re "Delete all trace state variables.*y or n.*$" { + send_gdb "y\n" + gdb_expect 30 { + -re "$gdb_prompt $" { + pass "Delete all trace state variables" + } + timeout { fail "Delete all trace state variables (timeout)" } + } + } + -re "$gdb_prompt $" { # This happens if there were no variables + } + timeout { perror "Delete all trace state variables (timeout)" ; return } + } + + gdb_test "info tvariables" \ + "Name\[\t \]+Initial\[\t \]+Current.*" \ + "List tvariables after deleting all" + +