/* readline defines this. */
#undef savestring
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
void (*deprecated_trace_find_hook) (char *arg, int from_tty);
void (*deprecated_trace_start_stop_hook) (int start, int from_tty);
-extern void (*deprecated_readline_begin_hook) (char *, ...);
-extern char *(*deprecated_readline_hook) (char *);
-extern void (*deprecated_readline_end_hook) (void);
-
/*
Tracepoint.c:
if (info != NULL)
{
VEC_free (mem_range_s, info->memory);
+ VEC_free (int, info->tvars);
xfree (info);
}
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)
{
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 *);
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. */
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. */
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,
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. */
}
}
}
+
+ append_exp (exp, &collect->computed);
break;
} /* switch */
do_cleanups (old_chain);
} /* 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;
+
+ *tdp_actions = NULL;
+ *stepping_actions = NULL;
- memrange_sortmerge (&tracepoint_list);
- memrange_sortmerge (&stepping_list);
+ 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
/* Reporting a run time is more readable than two long numbers. */
printf_filtered (_("Trace started at %ld.%06ld secs, stopped %ld.%06ld secs later.\n"),
- (long int) ts->start_time / 1000000,
- (long int) ts->start_time % 1000000,
- (long int) run_time / 1000000,
- (long int) run_time % 1000000);
+ (long int) (ts->start_time / 1000000),
+ (long int) (ts->start_time % 1000000),
+ (long int) (run_time / 1000000),
+ (long int) (run_time % 1000000));
}
else
printf_filtered (_("Trace started at %ld.%06ld secs.\n"),
- (long int) ts->start_time / 1000000,
- (long int) ts->start_time % 1000000);
+ (long int) (ts->start_time / 1000000),
+ (long int) (ts->start_time % 1000000));
}
else if (ts->stop_time)
printf_filtered (_("Trace stopped at %ld.%06ld secs.\n"),
- (long int) ts->stop_time / 1000000,
- (long int) ts->stop_time % 1000000);
+ (long int) (ts->stop_time / 1000000),
+ (long int) (ts->stop_time % 1000000));
/* Now report any per-tracepoint status available. */
tp_vec = all_tracepoints ();
char buf[100];
xsnprintf (buf, sizeof buf, "%ld.%06ld",
- (long int) ts->start_time / 1000000,
- (long int) ts->start_time % 1000000);
+ (long int) (ts->start_time / 1000000),
+ (long int) (ts->start_time % 1000000));
ui_out_field_string (uiout, "start-time", buf);
xsnprintf (buf, sizeof buf, "%ld.%06ld",
- (long int) ts->stop_time / 1000000,
- (long int) ts->stop_time % 1000000);
+ (long int) (ts->stop_time / 1000000),
+ (long int) (ts->stop_time % 1000000));
ui_out_field_string (uiout, "stop-time", buf);
}
}
else
print_what = SRC_AND_LOC;
- print_stack_frame (get_selected_frame (NULL), 1, print_what);
+ print_stack_frame (get_selected_frame (NULL), 1, print_what, 1);
do_displays ();
}
}
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;
tracepoint_number, traceframe_number);
old_chain = make_cleanup (null_cleanup, NULL);
+
+ /* This command only makes sense for the current frame, not the
+ selected frame. */
+ make_cleanup_restore_current_thread ();
+ select_frame (get_current_frame ());
+
actions = all_tracepoint_actions_and_cleanup (loc->owner);
trace_dump_actions (actions, 0, stepping_frame, from_tty);
writer->fp = gdb_fopen_cloexec (writer->pathname, "wb");
if (writer->fp == NULL)
error (_("Unable to open file '%s' for saving trace data (%s)"),
- filename, safe_strerror (errno));
+ writer->pathname, safe_strerror (errno));
}
/* This is the implementation of trace_file_write_ops method
fprintf (writer->fp, ";disconn:%x", ts->disconnected_tracing);
if (ts->circular_buffer)
fprintf (writer->fp, ";circular:%x", ts->circular_buffer);
+ if (ts->start_time)
+ {
+ fprintf (writer->fp, ";starttime:%s",
+ phex_nz (ts->start_time, sizeof (ts->start_time)));
+ }
+ if (ts->stop_time)
+ {
+ fprintf (writer->fp, ";stoptime:%s",
+ phex_nz (ts->stop_time, sizeof (ts->stop_time)));
+ }
if (ts->notes != NULL)
{
char *buf = (char *) alloca (strlen (ts->notes) * 2 + 1);
}
if (ex.reason < 0)
{
- /* Pop the partially set up target. */
- pop_target ();
+ /* Remove the partially set up target. */
+ unpush_target (&tfile_ops);
throw_exception (ex);
}
break;
}
case 'V':
+ {
+ int vnum;
+
+ tfile_read ((gdb_byte *) &vnum, 4);
+ VEC_safe_push (int, info->tvars, vnum);
+ }
case 'R':
case 'S':
{
r->length = *length_p;
}
+/* Handle the start of a <tvar> element. */
+
+static void
+traceframe_info_start_tvar (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct traceframe_info *info = user_data;
+ const char *id_attrib = xml_find_attribute (attributes, "id")->value;
+ int id = gdb_xml_parse_ulongest (parser, id_attrib);
+
+ VEC_safe_push (int, info->tvars, id);
+}
+
/* Discard the constructed trace frame info (if an error occurs). */
static void
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
+static const struct gdb_xml_attribute tvar_attributes[] = {
+ { "id", GDB_XML_AF_NONE, NULL, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
static const struct gdb_xml_element traceframe_info_children[] = {
{ "memory", memory_attributes, NULL,
GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
traceframe_info_start_memory, NULL },
+ { "tvar", tvar_attributes, NULL,
+ GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
+ traceframe_info_start_tvar, NULL },
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
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)