diff options
author | Yao Qi <yao@codesourcery.com> | 2013-06-26 08:17:27 +0000 |
---|---|---|
committer | Yao Qi <yao@codesourcery.com> | 2013-06-26 08:17:27 +0000 |
commit | dc673c81ae099d18e348ef2a7b93794cc9f8e33b (patch) | |
tree | 24e8dd7a0661b55651ced17b9254782f005ead77 | |
parent | e335d9cbd89a0a80bd2b0cbdcf60061d3ec75902 (diff) | |
download | fsf-binutils-gdb-dc673c81ae099d18e348ef2a7b93794cc9f8e33b.zip fsf-binutils-gdb-dc673c81ae099d18e348ef2a7b93794cc9f8e33b.tar.gz fsf-binutils-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.
-rw-r--r-- | gdb/ChangeLog | 32 | ||||
-rw-r--r-- | gdb/NEWS | 3 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 117 | ||||
-rw-r--r-- | gdb/mi/mi-cmds.c | 2 | ||||
-rw-r--r-- | gdb/mi/mi-cmds.h | 1 | ||||
-rw-r--r-- | gdb/mi/mi-main.c | 295 | ||||
-rw-r--r-- | gdb/remote.c | 2 | ||||
-rw-r--r-- | gdb/tracepoint.c | 145 | ||||
-rw-r--r-- | gdb/tracepoint.h | 48 |
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. @@ -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 */ |