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 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 ())
+ if (tvariables.empty () && !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");
+ 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 ();
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ for (const trace_state_variable &tsv : tvariables)
{
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));
+ uiout->field_string ("name", std::string ("$") + tsv.name);
+ uiout->field_string ("initial", plongest (tsv.initial_value));
- if (tsv->value_known)
- c = plongest (tsv->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
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");
}
}
case OP_VAR_VALUE:
{
struct symbol *sym = exp->elts[2].symbol;
- char_ptr name = (char_ptr) SYMBOL_NATURAL_NAME (sym);
+ const char *name = SYMBOL_NATURAL_NAME (sym);
collect->collect_symbol (exp->elts[2].symbol,
target_gdbarch (),
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 ();
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. */
if (utp->number == num && utp->addr == addr)
return utp;
- utp = XCNEW (struct uploaded_tp);
+ utp = new uploaded_tp;
utp->number = num;
utp->addr = addr;
- utp->actions = NULL;
- utp->step_actions = NULL;
- utp->cmd_strings = NULL;
utp->next = *utpp;
*utpp = utp;
while (*utpp)
{
next_one = (*utpp)->next;
- xfree (*utpp);
+ delete *utpp;
*utpp = next_one;
}
}
/* 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);
}
else if (piece == 'A')
{
utp = get_uploaded_tp (num, addr, utpp);
- VEC_safe_push (char_ptr, utp->actions, xstrdup (p));
+ utp->actions.push_back (xstrdup (p));
}
else if (piece == 'S')
{
utp = get_uploaded_tp (num, addr, utpp);
- VEC_safe_push (char_ptr, utp->step_actions, xstrdup (p));
+ utp->step_actions.push_back (xstrdup (p));
}
else if (piece == 'Z')
{
else if (startswith (srctype, "cond:"))
utp->cond_string = xstrdup (buf);
else if (startswith (srctype, "cmd:"))
- VEC_safe_push (char_ptr, utp->cmd_strings, xstrdup (buf));
+ utp->cmd_strings.push_back (xstrdup (buf));
}
else if (piece == 'V')
{
utsv->name = xstrdup (buf);
}
-void
-free_current_marker (void *arg)
-{
- struct static_tracepoint_marker **marker_p
- = (struct static_tracepoint_marker **) arg;
-
- if (*marker_p != NULL)
- {
- release_static_tracepoint_marker (*marker_p);
- xfree (*marker_p);
- }
- else
- *marker_p = NULL;
-}
-
/* Given a line of text defining a static tracepoint marker, parse it
into a "static tracepoint marker" object. Throws an error is
parsing fails. If PP is non-null, it points to one past the end of
void
parse_static_tracepoint_marker_definition (const char *line, const char **pp,
- struct static_tracepoint_marker *marker)
+ static_tracepoint_marker *marker)
{
const char *p, *endp;
ULONGEST addr;
- int end;
p = line;
p = unpack_varlen_hex (p, &addr);
if (endp == NULL)
error (_("bad marker definition: %s"), line);
- marker->str_id = (char *) xmalloc (endp - p + 1);
- end = hex2bin (p, (gdb_byte *) marker->str_id, (endp - p + 1) / 2);
- marker->str_id[end] = '\0';
-
- p += 2 * end;
- p++; /* skip a colon */
+ marker->str_id = hex2str (p, (endp - p) / 2);
- marker->extra = (char *) xmalloc (strlen (p) + 1);
- end = hex2bin (p, (gdb_byte *) marker->extra, strlen (p) / 2);
- marker->extra[end] = '\0';
+ p = endp;
+ p++; /* skip a colon */
- if (pp)
- *pp = p;
-}
+ /* This definition may be followed by another one, separated by a comma. */
+ int hex_len;
+ endp = strchr (p, ',');
+ if (endp != nullptr)
+ hex_len = endp - p;
+ else
+ hex_len = strlen (p);
-/* Release a static tracepoint marker's contents. Note that the
- object itself isn't released here. There objects are usually on
- the stack. */
+ marker->extra = hex2str (p, hex_len / 2);
-void
-release_static_tracepoint_marker (struct static_tracepoint_marker *marker)
-{
- xfree (marker->str_id);
- marker->str_id = NULL;
+ if (pp != nullptr)
+ *pp = p + hex_len;
}
/* Print MARKER to gdb_stdout. */
static void
print_one_static_tracepoint_marker (int count,
- struct static_tracepoint_marker *marker)
+ const static_tracepoint_marker &marker)
{
struct symbol *sym;
VEC(breakpoint_p) *tracepoints;
symtab_and_line sal;
- sal.pc = marker->address;
+ sal.pc = marker.address;
- tracepoints = static_tracepoints_here (marker->address);
+ tracepoints = static_tracepoints_here (marker.address);
ui_out_emit_tuple tuple_emitter (uiout, "marker");
identifier! */
uiout->field_int ("count", count);
- uiout->field_string ("marker-id", marker->str_id);
+ uiout->field_string ("marker-id", marker.str_id.c_str ());
uiout->field_fmt ("enabled", "%c",
!VEC_empty (breakpoint_p, tracepoints) ? 'y' : 'n');
strcpy (wrap_indent, " ");
- if (gdbarch_addr_bit (marker->gdbarch) <= 32)
+ if (gdbarch_addr_bit (marker.gdbarch) <= 32)
strcat (wrap_indent, " ");
else
strcat (wrap_indent, " ");
strcpy (extra_field_indent, " ");
- uiout->field_core_addr ("addr", marker->gdbarch, marker->address);
+ uiout->field_core_addr ("addr", marker.gdbarch, marker.address);
- sal = find_pc_line (marker->address, 0);
- sym = find_pc_sect_function (marker->address, NULL);
+ sal = find_pc_line (marker.address, 0);
+ sym = find_pc_sect_function (marker.address, NULL);
if (sym)
{
uiout->text ("in ");
uiout->text ("\n");
uiout->text (extra_field_indent);
uiout->text (_("Data: \""));
- uiout->field_string ("extra-data", marker->extra);
+ uiout->field_string ("extra-data", marker.extra.c_str ());
uiout->text ("\"\n");
if (!VEC_empty (breakpoint_p, tracepoints))
static void
info_static_tracepoint_markers_command (const char *arg, int from_tty)
{
- VEC(static_tracepoint_marker_p) *markers;
- struct cleanup *old_chain;
- struct static_tracepoint_marker *marker;
struct ui_out *uiout = current_uiout;
- int i;
+ std::vector<static_tracepoint_marker> markers
+ = target_static_tracepoint_markers_by_strid (NULL);
/* We don't have to check target_can_use_agent and agent's capability on
static tracepoint here, in order to be compatible with older GDBserver.
uiout->table_body ();
- markers = target_static_tracepoint_markers_by_strid (NULL);
- old_chain = make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers);
-
- for (i = 0;
- VEC_iterate (static_tracepoint_marker_p,
- markers, i, marker);
- i++)
- {
- print_one_static_tracepoint_marker (i + 1, marker);
- release_static_tracepoint_marker (marker);
- }
-
- do_cleanups (old_chain);
+ for (int i = 0; i < markers.size (); i++)
+ print_one_static_tracepoint_marker (i + 1, markers[i]);
}
/* The $_sdata convenience variable is a bit special. We don't know
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 (¤t_target, 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