aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorYao Qi <yao@codesourcery.com>2013-06-26 08:17:27 +0000
committerYao Qi <yao@codesourcery.com>2013-06-26 08:17:27 +0000
commitdc673c81ae099d18e348ef2a7b93794cc9f8e33b (patch)
tree24e8dd7a0661b55651ced17b9254782f005ead77 /gdb
parente335d9cbd89a0a80bd2b0cbdcf60061d3ec75902 (diff)
downloadgdb-dc673c81ae099d18e348ef2a7b93794cc9f8e33b.zip
gdb-dc673c81ae099d18e348ef2a7b93794cc9f8e33b.tar.gz
gdb-dc673c81ae099d18e348ef2a7b93794cc9f8e33b.tar.bz2
gdb/
2013-06-26 Pedro Alves <pedro@codesourcery.com> Yao Qi <yao@codesourcery.com> * gdb.texinfo (GDB/MI Tracepoint Commands): Document -trace-frame-collected. gdb: 2013-06-26 Pedro Alves <pedro@codesourcery.com> Yao Qi <yao@codesourcery.com> * mi/mi-cmds.c (mi_cmds): Register -trace-frame-collected. * mi/mi-cmds.h (mi_cmd_trace_frame_collected): Declare. * mi/mi-main.c (print_variable_or_computed): New function. (mi_cmd_trace_frame_collected): New function. * tracepoint.c (find_trace_state_variable_by_number): New. (struct traceframe_info): Move to tracepoint.h (struct collection_list): Likewise. (do_collect_symbol): Include locals and arguments in the wholly collected variables list. (clear_collection_list): Clear wholly collected variables list and computed variables list. (append_exp): New function. (encode_actions_1): Include variables in the wholly collected variables list. Include memory ranges and full-fledged expressions in the computed expressions list. (encode_actions): Move some code to ... Return the cleanup chain. (encode_actions_rsp): ... here. New function. (get_traceframe_location, get_traceframe_info): Remove static. * tracepoint.h (struct memrange): Moved from tracepoint.c. (struct collection_list): Moved from tracepoint.c. Add two new fields 'wholly_collected' and 'computed'. (find_trace_state_variable_by_number): Declare. (encode_actions): Adjust declaration. (encode_actions_rsp): Declare. (get_traceframe_info, get_traceframe_location): Declare. * NEWS: Mention new MI command -trace-frame-collected.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog32
-rw-r--r--gdb/NEWS3
-rw-r--r--gdb/doc/ChangeLog6
-rw-r--r--gdb/doc/gdb.texinfo117
-rw-r--r--gdb/mi/mi-cmds.c2
-rw-r--r--gdb/mi/mi-cmds.h1
-rw-r--r--gdb/mi/mi-main.c295
-rw-r--r--gdb/remote.c2
-rw-r--r--gdb/tracepoint.c145
-rw-r--r--gdb/tracepoint.h48
10 files changed, 597 insertions, 54 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0b0ff73..8c09ed5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,6 +1,38 @@
2013-06-26 Pedro Alves <pedro@codesourcery.com>
Yao Qi <yao@codesourcery.com>
+ * mi/mi-cmds.c (mi_cmds): Register -trace-frame-collected.
+ * mi/mi-cmds.h (mi_cmd_trace_frame_collected): Declare.
+ * mi/mi-main.c (print_variable_or_computed): New function.
+ (mi_cmd_trace_frame_collected): New function.
+ * tracepoint.c (find_trace_state_variable_by_number): New.
+ (struct traceframe_info): Move to tracepoint.h
+ (struct collection_list): Likewise.
+ (do_collect_symbol): Include locals and arguments in the
+ collected variables list.
+ (clear_collection_list): Clear wholly collected variables list
+ and computed variables list.
+ (append_exp): New function.
+ (encode_actions_1): Include variables in the wholly
+ collected variables list. Include memory ranges and
+ full-fledged expressions in the computed expressions list.
+ (encode_actions): Move some code to ...
+ Return the cleanup chain.
+ (encode_actions_rsp): ... here. New function.
+ (get_traceframe_location, get_traceframe_info): Remove static.
+ * tracepoint.h (struct memrange): Moved from tracepoint.c.
+ (struct collection_list): Moved from tracepoint.c. Add two
+ new fields 'wholly_collected' and 'computed'.
+ (find_trace_state_variable_by_number): Declare.
+ (encode_actions): Adjust declaration.
+ (encode_actions_rsp): Declare.
+ (get_traceframe_info, get_traceframe_location): Declare.
+
+ * NEWS: Mention new MI command -trace-frame-collected.
+
+2013-06-26 Pedro Alves <pedro@codesourcery.com>
+ Yao Qi <yao@codesourcery.com>
+
* ctf.c (ctf_traceframe_info): Push trace state variables
present in the trace data into the traceframe info object.
* breakpoint.c (DEF_VEC_I): Remove.
diff --git a/gdb/NEWS b/gdb/NEWS
index ab8f283..e469f1e 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -81,6 +81,9 @@ show range-stepping
"--skip-unavailable" option. When used, only the available registers
are displayed.
+ ** The new command -trace-frame-collected dumps collected variables,
+ computed expressions, tvars, memory and registers in a traceframe.
+
* New system-wide configuration scripts
A GDB installation now provides scripts suitable for use as system-wide
configuration scripts for the following systems:
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 5090ae9..285bb96 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,4 +1,10 @@
2013-06-26 Pedro Alves <pedro@codesourcery.com>
+ Yao Qi <yao@codesourcery.com>
+
+ * gdb.texinfo (GDB/MI Tracepoint Commands): Document
+ -trace-frame-collected.
+
+2013-06-26 Pedro Alves <pedro@codesourcery.com>
* gdb.texinfo (Traceframe Info Format): Document tvar element
and its attributes.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3992704..d75a3d1 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -33161,6 +33161,123 @@ with the @samp{$} character.
The corresponding @value{GDBN} command is @samp{tvariable}.
+@subheading The @code{-trace-frame-collected} Command
+@findex -trace-frame-collected
+
+@subsubheading Synopsis
+
+@smallexample
+ -trace-frame-collected
+ [--var-print-values @var{var_pval}]
+ [--comp-print-values @var{comp_pval}]
+ [--registers-format @var{regformat}]
+ [--memory-contents]
+@end smallexample
+
+This command returns the set of collected objects, register names,
+trace state variable names, memory ranges and computed expressions
+that have been collected at a particular trace frame. The optional
+parameters to the command affect the output format in different ways.
+See the output description table below for more details.
+
+The reported names can be used in the normal manner to create
+varobjs and inspect the objects themselves. The items returned by
+this command are categorized so that it is clear which is a variable,
+which is a register, which is a trace state variable, which is a
+memory range and which is a computed expression.
+
+For instance, if the actions were
+@smallexample
+collect myVar, myArray[myIndex], myObj.field, myPtr->field, myCount + 2
+collect *(int*)0xaf02bef0@@40
+@end smallexample
+
+@noindent
+the object collected in its entirety would be @code{myVar}. The
+object @code{myArray} would be partially collected, because only the
+element at index @code{myIndex} would be collected. The remaining
+objects would be computed expressions.
+
+An example output would be:
+
+@smallexample
+(gdb)
+-trace-frame-collected
+^done,
+ explicit-variables=[@{name="myVar",value="1"@}],
+ computed-expressions=[@{name="myArray[myIndex]",value="0"@},
+ @{name="myObj.field",value="0"@},
+ @{name="myPtr->field",value="1"@},
+ @{name="myCount + 2",value="3"@},
+ @{name="$tvar1 + 1",value="43970027"@}],
+ registers=[@{number="0",value="0x7fe2c6e79ec8"@},
+ @{number="1",value="0x0"@},
+ @{number="2",value="0x4"@},
+ ...
+ @{number="125",value="0x0"@}],
+ tvars=[@{name="$tvar1",current="43970026"@}],
+ memory=[@{address="0x0000000000602264",length="4"@},
+ @{address="0x0000000000615bc0",length="4"@}]
+(gdb)
+@end smallexample
+
+Where:
+
+@table @code
+@item explicit-variables
+The set of objects that have been collected in their entirety (as
+opposed to collecting just a few elements of an array or a few struct
+members). For each object, its name and value are printed.
+The @code{--var-print-values} option affects how or whether the value
+field is output. If @var{var_pval} is 0, then print only the names;
+if it is 1, print also their values; and if it is 2, print the name,
+type and value for simple data types, and the name and type for
+arrays, structures and unions.
+
+@item computed-expressions
+The set of computed expressions that have been collected at the
+current trace frame. The @code{--comp-print-values} option affects
+this set like the @code{--var-print-values} option affects the
+@code{explicit-variables} set. See above.
+
+@item registers
+The registers that have been collected at the current trace frame.
+For each register collected, the name and current value are returned.
+The value is formatted according to the @code{--registers-format}
+option. See the @command{-data-list-register-values} command for a
+list of the allowed formats. The default is @samp{x}.
+
+@item tvars
+The trace state variables that have been collected at the current
+trace frame. For each trace state variable collected, the name and
+current value are returned.
+
+@item memory
+The set of memory ranges that have been collected at the current trace
+frame. Its content is a list of tuples. Each tuple represents a
+collected memory range and has the following fields:
+
+@table @code
+@item address
+The start address of the memory range, as hexadecimal literal.
+
+@item length
+The length of the memory range, as decimal literal.
+
+@item contents
+The contents of the memory block, in hex. This field is only present
+if the @code{--memory-contents} option is specified.
+
+@end table
+
+@end table
+
+@subsubheading @value{GDBN} Command
+
+There is no corresponding @value{GDBN} command.
+
+@subsubheading Example
+
@subheading -trace-list-variables
@findex -trace-list-variables
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index eb67abe..0768b2a 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -148,6 +148,8 @@ static struct mi_cmd mi_cmds[] =
DEF_MI_CMD_MI ("trace-define-variable", mi_cmd_trace_define_variable),
DEF_MI_CMD_MI_1 ("trace-find", mi_cmd_trace_find,
&mi_suppress_notification.traceframe),
+ DEF_MI_CMD_MI ("trace-frame-collected",
+ mi_cmd_trace_frame_collected),
DEF_MI_CMD_MI ("trace-list-variables", mi_cmd_trace_list_variables),
DEF_MI_CMD_MI ("trace-save", mi_cmd_trace_save),
DEF_MI_CMD_MI ("trace-start", mi_cmd_trace_start),
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 8839319..a472582 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -94,6 +94,7 @@ 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_frame_collected;
extern mi_cmd_argv_ftype mi_cmd_trace_list_variables;
extern mi_cmd_argv_ftype mi_cmd_trace_save;
extern mi_cmd_argv_ftype mi_cmd_trace_start;
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 430d530..d6c763e 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2585,3 +2585,298 @@ mi_cmd_ada_task_info (char *command, char **argv, int argc)
print_ada_task_info (current_uiout, argv[0], current_inferior ());
}
+
+/* Print EXPRESSION according to VALUES. */
+
+static void
+print_variable_or_computed (char *expression, enum print_values values)
+{
+ struct expression *expr;
+ struct cleanup *old_chain;
+ struct value *val;
+ struct ui_file *stb;
+ struct value_print_options opts;
+ struct type *type;
+ struct ui_out *uiout = current_uiout;
+
+ stb = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (stb);
+
+ expr = parse_expression (expression);
+
+ make_cleanup (free_current_contents, &expr);
+
+ if (values == PRINT_SIMPLE_VALUES)
+ val = evaluate_type (expr);
+ else
+ val = evaluate_expression (expr);
+
+ if (values != PRINT_NO_VALUES)
+ make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_field_string (uiout, "name", expression);
+
+ switch (values)
+ {
+ case PRINT_SIMPLE_VALUES:
+ type = check_typedef (value_type (val));
+ type_print (value_type (val), "", stb, -1);
+ ui_out_field_stream (uiout, "type", stb);
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ {
+ struct value_print_options opts;
+
+ get_raw_print_options (&opts);
+ opts.deref_ref = 1;
+ common_val_print (val, stb, 0, &opts, current_language);
+ ui_out_field_stream (uiout, "value", stb);
+ }
+ break;
+ case PRINT_ALL_VALUES:
+ {
+ struct value_print_options opts;
+
+ get_raw_print_options (&opts);
+ opts.deref_ref = 1;
+ common_val_print (val, stb, 0, &opts, current_language);
+ ui_out_field_stream (uiout, "value", stb);
+ }
+ break;
+ }
+
+ do_cleanups (old_chain);
+}
+
+/* Implement the "-trace-frame-collected" command. */
+
+void
+mi_cmd_trace_frame_collected (char *command, char **argv, int argc)
+{
+ struct cleanup *old_chain;
+ struct bp_location *tloc;
+ int stepping_frame;
+ struct collection_list *clist;
+ struct collection_list tracepoint_list, stepping_list;
+ struct traceframe_info *tinfo;
+ int oind = 0;
+ int var_print_values = PRINT_ALL_VALUES;
+ int comp_print_values = PRINT_ALL_VALUES;
+ int registers_format = 'x';
+ int memory_contents = 0;
+ struct ui_out *uiout = current_uiout;
+ enum opt
+ {
+ VAR_PRINT_VALUES,
+ COMP_PRINT_VALUES,
+ REGISTERS_FORMAT,
+ MEMORY_CONTENTS,
+ };
+ static const struct mi_opt opts[] =
+ {
+ {"-var-print-values", VAR_PRINT_VALUES, 1},
+ {"-comp-print-values", COMP_PRINT_VALUES, 1},
+ {"-registers-format", REGISTERS_FORMAT, 1},
+ {"-memory-contents", MEMORY_CONTENTS, 0},
+ { 0, 0, 0 }
+ };
+
+ while (1)
+ {
+ char *oarg;
+ int opt = mi_getopt ("-trace-frame-collected", argc, argv, opts,
+ &oind, &oarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case VAR_PRINT_VALUES:
+ var_print_values = mi_parse_print_values (oarg);
+ break;
+ case COMP_PRINT_VALUES:
+ comp_print_values = mi_parse_print_values (oarg);
+ break;
+ case REGISTERS_FORMAT:
+ registers_format = oarg[0];
+ case MEMORY_CONTENTS:
+ memory_contents = 1;
+ break;
+ }
+ }
+
+ if (oind != argc)
+ error (_("Usage: -trace-frame-collected "
+ "[--var-print-values PRINT_VALUES] "
+ "[--comp-print-values PRINT_VALUES] "
+ "[--registers-format FORMAT]"
+ "[--memory-contents]"));
+
+ /* This throws an error is not inspecting a trace frame. */
+ tloc = get_traceframe_location (&stepping_frame);
+
+ /* This command only makes sense for the current frame, not the
+ selected frame. */
+ old_chain = make_cleanup_restore_current_thread ();
+ select_frame (get_current_frame ());
+
+ encode_actions_and_make_cleanup (tloc, &tracepoint_list,
+ &stepping_list);
+
+ if (stepping_frame)
+ clist = &stepping_list;
+ else
+ clist = &tracepoint_list;
+
+ tinfo = get_traceframe_info ();
+
+ /* Explicitly wholly collected variables. */
+ {
+ struct cleanup *list_cleanup;
+ char *p;
+ int i;
+
+ list_cleanup = make_cleanup_ui_out_list_begin_end (uiout,
+ "explicit-variables");
+ for (i = 0; VEC_iterate (char_ptr, clist->wholly_collected, i, p); i++)
+ print_variable_or_computed (p, var_print_values);
+ do_cleanups (list_cleanup);
+ }
+
+ /* Computed expressions. */
+ {
+ struct cleanup *list_cleanup;
+ char *p;
+ int i;
+
+ list_cleanup
+ = make_cleanup_ui_out_list_begin_end (uiout,
+ "computed-expressions");
+ for (i = 0; VEC_iterate (char_ptr, clist->computed, i, p); i++)
+ print_variable_or_computed (p, comp_print_values);
+ do_cleanups (list_cleanup);
+ }
+
+ /* Registers. Given pseudo-registers, and that some architectures
+ (like MIPS) actually hide the raw registers, we don't go through
+ the trace frame info, but instead consult the register cache for
+ register availability. */
+ {
+ struct cleanup *list_cleanup;
+ struct frame_info *frame;
+ struct gdbarch *gdbarch;
+ int regnum;
+ int numregs;
+
+ list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "registers");
+
+ frame = get_selected_frame (NULL);
+ gdbarch = get_frame_arch (frame);
+ numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
+
+ for (regnum = 0; regnum < numregs; regnum++)
+ {
+ if (gdbarch_register_name (gdbarch, regnum) == NULL
+ || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
+ continue;
+
+ output_register (frame, regnum, registers_format, 1);
+ }
+
+ do_cleanups (list_cleanup);
+ }
+
+ /* Trace state variables. */
+ {
+ struct cleanup *list_cleanup;
+ int tvar;
+ char *tsvname;
+ int i;
+
+ list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "tvars");
+
+ tsvname = NULL;
+ make_cleanup (free_current_contents, &tsvname);
+
+ for (i = 0; VEC_iterate (int, tinfo->tvars, i, tvar); i++)
+ {
+ struct cleanup *cleanup_child;
+ struct trace_state_variable *tsv;
+
+ tsv = find_trace_state_variable_by_number (tvar);
+
+ cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+ if (tsv != NULL)
+ {
+ tsvname = xrealloc (tsvname, strlen (tsv->name) + 2);
+ tsvname[0] = '$';
+ strcpy (tsvname + 1, tsv->name);
+ ui_out_field_string (uiout, "name", tsvname);
+
+ tsv->value_known = target_get_trace_state_variable_value (tsv->number,
+ &tsv->value);
+ ui_out_field_int (uiout, "current", tsv->value);
+ }
+ else
+ {
+ ui_out_field_skip (uiout, "name");
+ ui_out_field_skip (uiout, "current");
+ }
+
+ do_cleanups (cleanup_child);
+ }
+
+ do_cleanups (list_cleanup);
+ }
+
+ /* Memory. */
+ {
+ struct cleanup *list_cleanup;
+ VEC(mem_range_s) *available_memory = NULL;
+ struct mem_range *r;
+ int i;
+
+ traceframe_available_memory (&available_memory, 0, ULONGEST_MAX);
+ make_cleanup (VEC_cleanup(mem_range_s), &available_memory);
+
+ list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "memory");
+
+ for (i = 0; VEC_iterate (mem_range_s, available_memory, i, r); i++)
+ {
+ struct cleanup *cleanup_child;
+ gdb_byte *data;
+ struct gdbarch *gdbarch = target_gdbarch ();
+
+ cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+ ui_out_field_core_addr (uiout, "address", gdbarch, r->start);
+ ui_out_field_int (uiout, "length", r->length);
+
+ data = xmalloc (r->length);
+ make_cleanup (xfree, data);
+
+ if (memory_contents)
+ {
+ if (target_read_memory (r->start, data, r->length) == 0)
+ {
+ int m;
+ char *data_str, *p;
+
+ data_str = xmalloc (r->length * 2 + 1);
+ make_cleanup (xfree, data_str);
+
+ for (m = 0, p = data_str; m < r->length; ++m, p += 2)
+ sprintf (p, "%02x", data[m]);
+ ui_out_field_string (uiout, "contents", data_str);
+ }
+ else
+ ui_out_field_skip (uiout, "contents");
+ }
+ do_cleanups (cleanup_child);
+ }
+
+ do_cleanups (list_cleanup);
+ }
+
+ do_cleanups (old_chain);
+}
diff --git a/gdb/remote.c b/gdb/remote.c
index 7928f57..a29fe23 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -10527,7 +10527,7 @@ remote_download_tracepoint (struct bp_location *loc)
struct breakpoint *b = loc->owner;
struct tracepoint *t = (struct tracepoint *) b;
- encode_actions (loc, &tdp_actions, &stepping_actions);
+ encode_actions_rsp (loc, &tdp_actions, &stepping_actions);
old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
tdp_actions);
(void) make_cleanup (free_actions_list_cleanup_wrapper,
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 62b1a2c..4277843 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -340,6 +340,22 @@ find_trace_state_variable (const char *name)
return NULL;
}
+/* Look for a trace state variable of the given number. Return NULL if
+ not found. */
+
+struct trace_state_variable *
+find_trace_state_variable_by_number (int number)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ if (tsv->number == number)
+ return tsv;
+
+ return NULL;
+}
+
static void
delete_trace_state_variable (const char *name)
{
@@ -853,29 +869,6 @@ enum {
memrange_absolute = -1
};
-struct memrange
-{
- int type; /* memrange_absolute for absolute memory range,
- else basereg number. */
- bfd_signed_vma start;
- bfd_signed_vma end;
-};
-
-struct collection_list
- {
- unsigned char regs_mask[32]; /* room for up to 256 regs */
- long listsize;
- long next_memrange;
- struct memrange *list;
- long aexpr_listsize; /* size of array pointed to by expr_list elt */
- long next_aexpr_elt;
- struct agent_expr **aexpr_list;
-
- /* True is the user requested a collection of "$_sdata", "static
- tracepoint data". */
- int strace_data;
- };
-
/* MEMRANGE functions: */
static int memrange_cmp (const void *, const void *);
@@ -1166,6 +1159,9 @@ do_collect_symbol (const char *print_name,
collect_symbol (p->collect, sym, p->gdbarch, p->frame_regno,
p->frame_offset, p->pc, p->trace_string);
p->count++;
+
+ VEC_safe_push (char_ptr, p->collect->wholly_collected,
+ xstrdup (print_name));
}
/* Add all locals (or args) symbols to collection list. */
@@ -1242,6 +1238,9 @@ clear_collection_list (struct collection_list *list)
xfree (list->aexpr_list);
xfree (list->list);
+
+ VEC_free (char_ptr, list->wholly_collected);
+ VEC_free (char_ptr, list->computed);
}
/* A cleanup wrapper for function clear_collection_list. */
@@ -1392,6 +1391,21 @@ stringify_collection_list (struct collection_list *list)
return *str_list;
}
+/* Add the printed expression EXP to *LIST. */
+
+static void
+append_exp (struct expression *exp, VEC(char_ptr) **list)
+{
+ struct ui_file *tmp_stream = mem_fileopen ();
+ char *text;
+
+ print_expression (exp, tmp_stream);
+
+ text = ui_file_xstrdup (tmp_stream, NULL);
+
+ VEC_safe_push (char_ptr, *list, text);
+ ui_file_delete (tmp_stream);
+}
static void
encode_actions_1 (struct command_line *action,
@@ -1537,16 +1551,25 @@ encode_actions_1 (struct command_line *action,
check_typedef (exp->elts[1].type);
add_memrange (collect, memrange_absolute, addr,
TYPE_LENGTH (exp->elts[1].type));
+ append_exp (exp, &collect->computed);
break;
case OP_VAR_VALUE:
- collect_symbol (collect,
- exp->elts[2].symbol,
- tloc->gdbarch,
- frame_reg,
- frame_offset,
- tloc->address,
- trace_string);
+ {
+ struct symbol *sym = exp->elts[2].symbol;
+ char_ptr name = (char_ptr) SYMBOL_NATURAL_NAME (sym);
+
+ collect_symbol (collect,
+ exp->elts[2].symbol,
+ tloc->gdbarch,
+ frame_reg,
+ frame_offset,
+ tloc->address,
+ trace_string);
+ VEC_safe_push (char_ptr,
+ collect->wholly_collected,
+ name);
+ }
break;
default: /* Full-fledged expression. */
@@ -1582,6 +1605,8 @@ encode_actions_1 (struct command_line *action,
}
}
}
+
+ append_exp (exp, &collect->computed);
break;
} /* switch */
do_cleanups (old_chain);
@@ -1635,46 +1660,64 @@ encode_actions_1 (struct command_line *action,
} /* for */
}
-/* Render all actions into gdb protocol. */
+/* Encode actions of tracepoint TLOC->owner and fill TRACEPOINT_LIST
+ and STEPPING_LIST. Return a cleanup pointer to clean up both
+ TRACEPOINT_LIST and STEPPING_LIST. */
-void
-encode_actions (struct bp_location *tloc, char ***tdp_actions,
- char ***stepping_actions)
+struct cleanup *
+encode_actions_and_make_cleanup (struct bp_location *tloc,
+ struct collection_list *tracepoint_list,
+ struct collection_list *stepping_list)
{
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;
- struct collection_list tracepoint_list, stepping_list;
-
- back_to = make_cleanup (null_cleanup, NULL);
+ struct cleanup *back_to, *return_chain;
- init_collection_list (&tracepoint_list);
- init_collection_list (&stepping_list);
+ return_chain = make_cleanup (null_cleanup, NULL);
+ init_collection_list (tracepoint_list);
+ init_collection_list (stepping_list);
- make_cleanup (do_clear_collection_list, &tracepoint_list);
- make_cleanup (do_clear_collection_list, &stepping_list);
-
- *tdp_actions = NULL;
- *stepping_actions = NULL;
+ make_cleanup (do_clear_collection_list, tracepoint_list);
+ make_cleanup (do_clear_collection_list, stepping_list);
+ back_to = make_cleanup (null_cleanup, NULL);
gdbarch_virtual_frame_pointer (tloc->gdbarch,
tloc->address, &frame_reg, &frame_offset);
actions = all_tracepoint_actions_and_cleanup (tloc->owner);
encode_actions_1 (actions, tloc, frame_reg, frame_offset,
- &tracepoint_list, &stepping_list);
+ tracepoint_list, stepping_list);
+
+ memrange_sortmerge (tracepoint_list);
+ memrange_sortmerge (stepping_list);
+
+ do_cleanups (back_to);
+ return return_chain;
+}
+
+/* Render all actions into gdb protocol. */
+
+void
+encode_actions_rsp (struct bp_location *tloc, char ***tdp_actions,
+ char ***stepping_actions)
+{
+ struct collection_list tracepoint_list, stepping_list;
+ struct cleanup *cleanup;
- memrange_sortmerge (&tracepoint_list);
- memrange_sortmerge (&stepping_list);
+ *tdp_actions = NULL;
+ *stepping_actions = NULL;
+
+ cleanup = encode_actions_and_make_cleanup (tloc, &tracepoint_list,
+ &stepping_list);
*tdp_actions = stringify_collection_list (&tracepoint_list);
*stepping_actions = stringify_collection_list (&stepping_list);
- do_cleanups (back_to);
+ do_cleanups (cleanup);
}
static void
@@ -2938,7 +2981,7 @@ trace_dump_actions (struct command_line *action,
traceframe. Set *STEPPING_FRAME_P to 1 if the current traceframe
is a stepping traceframe. */
-static struct bp_location *
+struct bp_location *
get_traceframe_location (int *stepping_frame_p)
{
struct tracepoint *t;
@@ -5673,7 +5716,7 @@ parse_traceframe_info (const char *tframe_info)
This is where we avoid re-fetching the object from the target if we
already have it cached. */
-static struct traceframe_info *
+struct traceframe_info *
get_traceframe_info (void)
{
if (traceframe_info == NULL)
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index 350ab5e..9a874eb 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -323,6 +323,38 @@ struct trace_file_writer
const struct trace_file_write_ops *ops;
};
+struct memrange
+{
+ /* memrange_absolute for absolute memory range, else basereg
+ number. */
+ int type;
+ bfd_signed_vma start;
+ bfd_signed_vma end;
+};
+
+struct collection_list
+{
+ /* room for up to 256 regs */
+ unsigned char regs_mask[32];
+ long listsize;
+ long next_memrange;
+ struct memrange *list;
+
+ /* size of array pointed to by expr_list elt. */
+ long aexpr_listsize;
+ long next_aexpr_elt;
+ struct agent_expr **aexpr_list;
+
+ /* True is the user requested a collection of "$_sdata", "static
+ tracepoint data". */
+ int strace_data;
+
+ /* A set of names of wholly collected objects. */
+ VEC(char_ptr) *wholly_collected;
+ /* A set of computed expressions. */
+ VEC(char_ptr) *computed;
+};
+
extern void parse_static_tracepoint_marker_definition
(char *line, char **pp,
struct static_tracepoint_marker *marker);
@@ -360,13 +392,21 @@ void free_actions (struct breakpoint *);
extern const char *decode_agent_options (const char *exp, int *trace_string);
-extern void encode_actions (struct bp_location *tloc,
- char ***tdp_actions, char ***stepping_actions);
+extern struct cleanup *
+ encode_actions_and_make_cleanup (struct bp_location *tloc,
+ struct collection_list *tracepoint_list,
+ struct collection_list *stepping_list);
+
+extern void encode_actions_rsp (struct bp_location *tloc,
+ char ***tdp_actions, char ***stepping_actions);
extern void validate_actionline (const char *, struct breakpoint *);
extern void validate_trace_state_variable_name (const char *name);
extern struct trace_state_variable *find_trace_state_variable (const char *name);
+extern struct trace_state_variable *
+ find_trace_state_variable_by_number (int number);
+
extern struct trace_state_variable *create_trace_state_variable (const char *name);
extern int encode_source_string (int num, ULONGEST addr,
@@ -416,4 +456,8 @@ extern struct traceframe_info *parse_traceframe_info (const char *tframe_info);
extern int traceframe_available_memory (VEC(mem_range_s) **result,
CORE_ADDR memaddr, ULONGEST len);
+extern struct traceframe_info *get_traceframe_info (void);
+
+extern struct bp_location *get_traceframe_location (int *stepping_frame_p);
+
#endif /* TRACEPOINT_H */