any of these for any reason - API is by name or number only - so it
works to have a vector of objects. */
-typedef struct trace_state_variable tsv_s;
-DEF_VEC_O(tsv_s);
-
-static VEC(tsv_s) *tvariables;
+static std::vector<trace_state_variable> tvariables;
/* The next integer to assign to a variable. */
struct collection_list;
static char *mem2hex (gdb_byte *, char *, int);
-static struct command_line *
- all_tracepoint_actions_and_cleanup (struct breakpoint *t);
+static counted_command_line all_tracepoint_actions (struct breakpoint *);
static struct trace_status trace_status;
struct trace_state_variable *
create_trace_state_variable (const char *name)
{
- struct trace_state_variable tsv;
-
- memset (&tsv, 0, sizeof (tsv));
- tsv.name = xstrdup (name);
- tsv.number = next_tsv_number++;
- return VEC_safe_push (tsv_s, tvariables, &tsv);
+ tvariables.emplace_back (name, next_tsv_number++);
+ return &tvariables.back ();
}
/* Look for a trace state variable of the given name. */
struct trace_state_variable *
find_trace_state_variable (const char *name)
{
- struct trace_state_variable *tsv;
- int ix;
-
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- if (strcmp (name, tsv->name) == 0)
- return tsv;
+ for (trace_state_variable &tsv : tvariables)
+ if (tsv.name == name)
+ return &tsv;
return NULL;
}
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;
+ for (trace_state_variable &tsv : tvariables)
+ if (tsv.number == number)
+ return &tsv;
return NULL;
}
static void
delete_trace_state_variable (const char *name)
{
- struct trace_state_variable *tsv;
- int ix;
-
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- if (strcmp (name, tsv->name) == 0)
+ for (auto it = tvariables.begin (); it != tvariables.end (); it++)
+ if (it->name == name)
{
- gdb::observers::tsv_deleted.notify (tsv);
-
- xfree ((void *)tsv->name);
- VEC_unordered_remove (tsv_s, tvariables, ix);
-
+ gdb::observers::tsv_deleted.notify (&*it);
+ tvariables.erase (it);
return;
}
}
printf_filtered (_("Trace state variable $%s "
"now has initial value %s.\n"),
- tsv->name, plongest (tsv->initial_value));
+ tsv->name.c_str (), plongest (tsv->initial_value));
return;
}
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
- tsv->name, plongest (tsv->initial_value));
+ tsv->name.c_str (), plongest (tsv->initial_value));
}
static void
if (args == NULL)
{
if (query (_("Delete all trace state variables? ")))
- VEC_free (tsv_s, tvariables);
+ tvariables.clear ();
dont_repeat ();
gdb::observers::tsv_deleted.notify (NULL);
return;
void
tvariables_info_1 (void)
{
- struct trace_state_variable *tsv;
- int ix;
- int count = 0;
struct ui_out *uiout = current_uiout;
- if (VEC_length (tsv_s, tvariables) == 0 && !uiout->is_mi_like_p ())
- {
- printf_filtered (_("No trace state variables.\n"));
- return;
- }
-
/* Try to acquire values from the target. */
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix, ++count)
- tsv->value_known = target_get_trace_state_variable_value (tsv->number,
- &(tsv->value));
+ for (trace_state_variable &tsv : tvariables)
+ tsv.value_known
+ = target_get_trace_state_variable_value (tsv.number, &tsv.value);
- ui_out_emit_table table_emitter (uiout, 3, count, "trace-variables");
- uiout->table_header (15, ui_left, "name", "Name");
- uiout->table_header (11, ui_left, "initial", "Initial");
- uiout->table_header (11, ui_left, "current", "Current");
+ {
+ ui_out_emit_table table_emitter (uiout, 3, tvariables.size (),
+ "trace-variables");
+ uiout->table_header (15, ui_left, "name", "Name");
+ uiout->table_header (11, ui_left, "initial", "Initial");
+ uiout->table_header (11, ui_left, "current", "Current");
- uiout->table_body ();
+ uiout->table_body ();
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- {
- const char *c;
-
- ui_out_emit_tuple tuple_emitter (uiout, "variable");
-
- std::string name = std::string ("$") + tsv->name;
- uiout->field_string ("name", name.c_str ());
- uiout->field_string ("initial", plongest (tsv->initial_value));
-
- if (tsv->value_known)
- c = plongest (tsv->value);
- else if (uiout->is_mi_like_p ())
- /* For MI, we prefer not to use magic string constants, but rather
- omit the field completely. The difference between unknown and
- undefined does not seem important enough to represent. */
- c = NULL;
- else if (current_trace_status ()->running || traceframe_number >= 0)
- /* The value is/was defined, but we don't have it. */
- c = "<unknown>";
- else
- /* It is not meaningful to ask about the value. */
- c = "<undefined>";
- if (c)
- uiout->field_string ("current", c);
- uiout->text ("\n");
- }
+ for (const trace_state_variable &tsv : tvariables)
+ {
+ const char *c;
+
+ ui_out_emit_tuple tuple_emitter (uiout, "variable");
+
+ uiout->field_string ("name", std::string ("$") + tsv.name);
+ uiout->field_string ("initial", plongest (tsv.initial_value));
+
+ if (tsv.value_known)
+ c = plongest (tsv.value);
+ else if (uiout->is_mi_like_p ())
+ /* For MI, we prefer not to use magic string constants, but rather
+ omit the field completely. The difference between unknown and
+ undefined does not seem important enough to represent. */
+ c = NULL;
+ else if (current_trace_status ()->running || traceframe_number >= 0)
+ /* The value is/was defined, but we don't have it. */
+ c = "<unknown>";
+ else
+ /* It is not meaningful to ask about the value. */
+ c = "<undefined>";
+ if (c)
+ uiout->field_string ("current", c);
+ uiout->text ("\n");
+ }
+ }
+
+ if (tvariables.empty ())
+ uiout->text (_("No trace state variables.\n"));
}
/* List all the trace state variables. */
void
save_trace_state_variables (struct ui_file *fp)
{
- struct trace_state_variable *tsv;
- int ix;
-
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ for (const trace_state_variable &tsv : tvariables)
{
- fprintf_unfiltered (fp, "tvariable $%s", tsv->name);
- if (tsv->initial_value)
- fprintf_unfiltered (fp, " = %s", plongest (tsv->initial_value));
+ fprintf_unfiltered (fp, "tvariable $%s", tsv.name.c_str ());
+ if (tsv.initial_value)
+ fprintf_unfiltered (fp, " = %s", plongest (tsv.initial_value));
fprintf_unfiltered (fp, "\n");
}
}
string_printf ("Enter actions for tracepoint %d, one per line.",
t->number);
- command_line_up l = read_command_lines (&tmpbuf[0], from_tty, 1,
- check_tracepoint_command, t);
+ counted_command_line l = read_command_lines (&tmpbuf[0], from_tty, 1,
+ check_tracepoint_command,
+ t);
breakpoint_set_commands (t, std::move (l));
}
/* else just return */
here. */
gdb_assert (stepping_list);
- encode_actions_1 (action->body_list[0], tloc, frame_reg,
+ encode_actions_1 (action->body_list_0.get (), tloc, frame_reg,
frame_offset, stepping_list, NULL);
}
else
struct collection_list *tracepoint_list,
struct collection_list *stepping_list)
{
- struct command_line *actions;
int frame_reg;
LONGEST frame_offset;
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,
+ counted_command_line actions = all_tracepoint_actions (tloc->owner);
+ encode_actions_1 (actions.get (), tloc, frame_reg, frame_offset,
tracepoint_list, stepping_list);
+ encode_actions_1 (breakpoint_commands (tloc->owner), tloc,
+ frame_reg, frame_offset, tracepoint_list, stepping_list);
tracepoint_list->finish ();
stepping_list->finish ();
VEC_free (breakpoint_p, tp_vec);
/* Send down all the trace state variables too. */
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- {
- target_download_trace_state_variable (tsv);
- }
+ for (const trace_state_variable &tsv : tvariables)
+ target_download_trace_state_variable (tsv);
/* Tell target to treat text-like sections as transparent. */
target_trace_set_readonly_regions ();
if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
{
- int i;
-
- for (i = 0; i < action->body_count; ++i)
- trace_dump_actions (action->body_list[i],
- 1, stepping_frame, from_tty);
+ gdb_assert (action->body_list_1 == nullptr);
+ trace_dump_actions (action->body_list_0.get (),
+ 1, stepping_frame, from_tty);
}
else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
{
return t->loc;
}
-/* Return all the actions, including default collect, of a tracepoint
- T. It constructs cleanups into the chain, and leaves the caller to
- handle them (call do_cleanups). */
+/* Return the default collect actions of a tracepoint T. */
-static struct command_line *
-all_tracepoint_actions_and_cleanup (struct breakpoint *t)
+static counted_command_line
+all_tracepoint_actions (struct breakpoint *t)
{
- struct command_line *actions;
-
- actions = breakpoint_commands (t);
+ counted_command_line actions (nullptr, command_lines_deleter ());
/* If there are default expressions to collect, make up a collect
action and prepend to the action list to encode. Note that since
if (*default_collect)
{
struct command_line *default_collect_action;
- char *default_collect_line;
-
- default_collect_line = xstrprintf ("collect %s", default_collect);
- make_cleanup (xfree, default_collect_line);
+ gdb::unique_xmalloc_ptr<char> default_collect_line
+ (xstrprintf ("collect %s", default_collect));
- validate_actionline (default_collect_line, t);
- default_collect_action = XNEW (struct command_line);
- make_cleanup (xfree, default_collect_action);
- default_collect_action->next = actions;
- default_collect_action->line = default_collect_line;
- actions = default_collect_action;
+ validate_actionline (default_collect_line.get (), t);
+ actions.reset (new struct command_line (simple_control,
+ default_collect_line.release ()),
+ command_lines_deleter ());
}
return actions;
{
int stepping_frame = 0;
struct bp_location *loc;
- struct command_line *actions;
/* This throws an error is not inspecting a trace frame. */
loc = get_traceframe_location (&stepping_frame);
select_frame (get_current_frame ());
- actions = all_tracepoint_actions_and_cleanup (loc->owner);
+ counted_command_line actions = all_tracepoint_actions (loc->owner);
- trace_dump_actions (actions, 0, stepping_frame, from_tty);
+ trace_dump_actions (actions.get (), 0, stepping_frame, from_tty);
+ trace_dump_actions (breakpoint_commands (loc->owner), 0, stepping_frame,
+ from_tty);
}
/* Encode a piece of a tracepoint's source-level definition in a form
clear_traceframe_info ();
}
-/* A cleanup used when switching away and back from tfind mode. */
-
-struct current_traceframe_cleanup
-{
- /* The traceframe we were inspecting. */
- int traceframe_number;
-};
-
-static void
-do_restore_current_traceframe_cleanup (void *arg)
-{
- struct current_traceframe_cleanup *old
- = (struct current_traceframe_cleanup *) arg;
-
- set_current_traceframe (old->traceframe_number);
-}
-
-static void
-restore_current_traceframe_cleanup_dtor (void *arg)
-{
- struct current_traceframe_cleanup *old
- = (struct current_traceframe_cleanup *) arg;
-
- xfree (old);
-}
-
-struct cleanup *
-make_cleanup_restore_current_traceframe (void)
-{
- struct current_traceframe_cleanup *old =
- XNEW (struct current_traceframe_cleanup);
-
- old->traceframe_number = traceframe_number;
-
- return make_cleanup_dtor (do_restore_current_traceframe_cleanup, old,
- restore_current_traceframe_cleanup_dtor);
-}
+scoped_restore_current_traceframe::scoped_restore_current_traceframe ()
+: m_traceframe_number (traceframe_number)
+{}
/* Given a number and address, return an uploaded tracepoint with that
number, creating if necessary. */
/* Most likely some numbers will have to be reassigned as part of
the merge, so clear them all in anticipation. */
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- tsv->number = 0;
+ for (trace_state_variable &tsv : tvariables)
+ tsv.number = 0;
for (utsv = *uploaded_tsvs; utsv; utsv = utsv->next)
{
if (info_verbose)
printf_filtered (_("Assuming trace state variable $%s "
"is same as target's variable %d.\n"),
- tsv->name, utsv->number);
+ tsv->name.c_str (), utsv->number);
}
else
{
if (info_verbose)
printf_filtered (_("Created trace state variable "
"$%s for target's variable %d.\n"),
- tsv->name, utsv->number);
+ tsv->name.c_str (), utsv->number);
}
/* Give precedence to numberings that come from the target. */
if (tsv)
/* Renumber everything that didn't get a target-assigned number. */
highest = 0;
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- if (tsv->number > highest)
- highest = tsv->number;
+ for (const trace_state_variable &tsv : tvariables)
+ highest = std::max (tsv.number, highest);
++highest;
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- if (tsv->number == 0)
- tsv->number = highest++;
+ for (trace_state_variable &tsv : tvariables)
+ if (tsv.number == 0)
+ tsv.number = highest++;
free_uploaded_tsvs (uploaded_tsvs);
}
sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
void *ignore)
{
- LONGEST size;
- gdb_byte *buf;
-
/* We need to read the whole object before we know its size. */
- size = target_read_alloc (¤t_target,
- TARGET_OBJECT_STATIC_TRACE_DATA,
- NULL, &buf);
- if (size >= 0)
+ gdb::optional<gdb::byte_vector> buf
+ = target_read_alloc (target_stack, TARGET_OBJECT_STATIC_TRACE_DATA,
+ NULL);
+ if (buf)
{
struct value *v;
struct type *type;
type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
- size);
+ buf->size ());
v = allocate_value (type);
- memcpy (value_contents_raw (v), buf, size);
- xfree (buf);
+ memcpy (value_contents_raw (v), buf->data (), buf->size ());
return v;
}
else