This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 5/6] New MI command -trace-frame-collected


On 06/17/2013 11:31 PM, Eli Zaretskii wrote:
> How can it not be important, when (AFAIU) the collection commands are
> those that determine whether an object is collected in whole or only
> partially?  By the time the user gets to displaying the collected
> data, it's too late to decide about that.  Or am I missing something?
> 
> If I'm right, then it is important to describe this with tracepoint
> actions because that is where the user needs to decide what to collect
> and how.
> 
> On second thought, I still don't understand why is it so important to
> emphasize this issue.  Isn't it trivially clear that in your example
> myVar is collected in its entirety, while for myArray, only its
> myIndex'th element is collected, and that the rest are expressions?

Right.

> Why do we need to explain that?  Isn't it enough to say
> 
>    @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).
> 

It is simple to enough to explain "explicit-variables".

> If this is good enough, then this paragraph:
> 
>> >+This command returns the set of explicitly wholly collected (explained
>> >+below with an example) 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.
> Needs to be rephrased to not mention the "explicitly wholly" thing.
> 

Agreed.  I removed "explicitly wholly" thing.

>> >What do you think?
> I don't like the result, sorry.
> 
> First, "explicitly wholly" sounds awkward, so much so that the reader
> might decide this is a mistake of some kind.  Please use "collected
> wholly" or "explicitly collected as a whole", if I didn't convince you
> that the entire point about this is moot.
> 
> Second, this issue is too complicated to explain it with an example.
> You need to provide rules by which the user will be able to decide
> whether some data will be collected as a whole or not.
> 

As "explicitly wholly" is removed from the patch, we don't need
complicated explanation.  So rules are not added.

> Third, you need @noindent here:
> 
>> >+@smallexample
>> >+collect myVar, myArray[myIndex] myObj.field, myPtr->field, myCount + 2
>> >+collect *(int*)0xaf02bef0@@40
>> >+@end smallexample
>> >+the set of named objects explicitly wholly collected would be
> after the "@end smallexample" line.

Fixed.

-- 
Yao (éå)

gdb/doc:

2013-06-17  Pedro Alves  <pedro@codesourcery.com>
	    Yao Qi  <yao@codesourcery.com>

	* gdb.texinfo (GDB/MI Tracepoint Commands): Document
	-trace-frame-collected.
gdb:

2013-06-17  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.
---
 gdb/NEWS            |    3 +
 gdb/doc/gdb.texinfo |  117 ++++++++++++++++++++
 gdb/mi/mi-cmds.c    |    2 +
 gdb/mi/mi-cmds.h    |    1 +
 gdb/mi/mi-main.c    |  297 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/remote.c        |    2 +-
 gdb/tracepoint.c    |  144 ++++++++++++++++---------
 gdb/tracepoint.h    |   47 ++++++++-
 8 files changed, 559 insertions(+), 54 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 2c66db7..3d5c876 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -80,6 +80,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/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3992704..8de1c2f 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}.  Object
+@code{myArray} is partially collected, because only element on index
+@code{myIndex} is collected.  The rest of objects are 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..0b8740da 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2585,3 +2585,300 @@ 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 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 ());
+
+  {
+    struct collection_list tracepoint_list, stepping_list;
+
+    encode_actions (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 080d048..d06b1ed 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -10524,7 +10524,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 d7d0e88..4f10c93 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -340,6 +340,22 @@ find_trace_state_variable (const char *name)
   return NULL;
 }
 
+/* Return the tsv if its number is 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,63 @@ 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 (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);
+  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 (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 +2980,7 @@ trace_dump_actions (struct command_line *action,
    traceframe.  Set *STEPPING_FRAME_P to 1 if the current traceframe
    is the stepping traceframe.  */
 
-static struct bp_location *
+struct bp_location *
 get_traceframe_location (int *stepping_frame_p)
 {
   struct tracepoint *t;
@@ -5673,7 +5715,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..e79ba3a 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,20 @@ 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 (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 +455,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 */
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]