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.
This commit is contained in:
parent
e335d9cbd8
commit
dc673c81ae
10 changed files with 598 additions and 55 deletions
|
@ -1,3 +1,35 @@
|
|||
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>
|
||||
|
||||
|
|
3
gdb/NEWS
3
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:
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
295
gdb/mi/mi-main.c
295
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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
147
gdb/tracepoint.c
147
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;
|
||||
struct cleanup *back_to, *return_chain;
|
||||
|
||||
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);
|
||||
|
||||
back_to = 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;
|
||||
|
||||
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);
|
||||
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;
|
||||
|
||||
*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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue