/* Tracing functionality for remote targets in custom GDB protocol
- Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of GDB.
yet attempted to fetch it, or if the target does not support
fetching this object, or if we're not inspecting a traceframe
presently. */
-static struct traceframe_info *traceframe_info;
+static traceframe_info_up current_traceframe_info;
/* Tracing command lists. */
static struct cmd_list_element *tfindlist;
char *trace_stop_notes = NULL;
-/* ======= Important command functions: ======= */
-static void actions_command (char *, int);
-static void tstart_command (char *, int);
-static void tstop_command (char *, int);
-static void tstatus_command (char *, int);
-static void tfind_pc_command (char *, int);
-static void tfind_tracepoint_command (char *, int);
-static void tfind_line_command (char *, int);
-static void tfind_range_command (char *, int);
-static void tfind_outside_command (char *, int);
-static void tdump_command (char *, int);
-
/* support routines */
struct collection_list;
static struct command_line *
all_tracepoint_actions_and_cleanup (struct breakpoint *t);
-extern void _initialize_tracepoint (void);
-
static struct trace_status trace_status;
const char *stop_reason_names[] = {
return &trace_status;
}
-/* Destroy INFO. */
-
-static void
-free_traceframe_info (struct traceframe_info *info)
-{
- if (info != NULL)
- {
- VEC_free (mem_range_s, info->memory);
- VEC_free (int, info->tvars);
-
- xfree (info);
- }
-}
-
/* Free and clear the traceframe info cache of the current
traceframe. */
static void
clear_traceframe_info (void)
{
- free_traceframe_info (traceframe_info);
- traceframe_info = NULL;
+ current_traceframe_info = NULL;
}
/* Set traceframe number to NUM. */
{
CORE_ADDR trace_pc;
struct symbol *traceframe_fun;
- struct symtab_and_line traceframe_sal;
+ symtab_and_line traceframe_sal;
/* Save as globals for internal use. */
if (trace_frame != NULL
}
else
{
- init_sal (&traceframe_sal);
traceframe_fun = NULL;
set_internalvar_integer (lookup_internalvar ("trace_line"), -1);
}
evaluate into an initial value. */
static void
-trace_variable_command (char *args, int from_tty)
+trace_variable_command (const char *args, int from_tty)
{
- struct cleanup *old_chain;
LONGEST initval = 0;
struct trace_state_variable *tsv;
- char *name, *p;
+ const char *name_start, *p;
if (!args || !*args)
error_no_arg (_("Syntax is $NAME [ = EXPR ]"));
if (*p++ != '$')
error (_("Name of trace variable should start with '$'"));
- name = p;
+ name_start = p;
while (isalnum (*p) || *p == '_')
p++;
- name = savestring (name, p - name);
- old_chain = make_cleanup (xfree, name);
+ std::string name (name_start, p - name_start);
p = skip_spaces (p);
if (*p != '=' && *p != '\0')
error (_("Syntax must be $NAME [ = EXPR ]"));
- validate_trace_state_variable_name (name);
+ validate_trace_state_variable_name (name.c_str ());
if (*p == '=')
initval = value_as_long (parse_and_eval (++p));
/* If the variable already exists, just change its initial value. */
- tsv = find_trace_state_variable (name);
+ tsv = find_trace_state_variable (name.c_str ());
if (tsv)
{
if (tsv->initial_value != initval)
printf_filtered (_("Trace state variable $%s "
"now has initial value %s.\n"),
tsv->name, plongest (tsv->initial_value));
- do_cleanups (old_chain);
return;
}
/* Create a new variable. */
- tsv = create_trace_state_variable (name);
+ tsv = create_trace_state_variable (name.c_str ());
tsv->initial_value = initval;
observer_notify_tsv_created (tsv);
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
tsv->name, plongest (tsv->initial_value));
-
- do_cleanups (old_chain);
}
static void
-delete_trace_variable_command (char *args, int from_tty)
+delete_trace_variable_command (const char *args, int from_tty)
{
- int ix;
- char **argv;
- struct cleanup *back_to;
-
if (args == NULL)
{
if (query (_("Delete all trace state variables? ")))
return;
}
- argv = gdb_buildargv (args);
- back_to = make_cleanup_freeargv (argv);
+ gdb_argv argv (args);
- for (ix = 0; argv[ix] != NULL; ix++)
+ for (char *arg : argv)
{
- if (*argv[ix] == '$')
- delete_trace_state_variable (argv[ix] + 1);
+ if (*arg == '$')
+ delete_trace_state_variable (arg + 1);
else
- warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[ix]);
+ warning (_("Name \"%s\" not prefixed with '$', ignoring"), arg);
}
- do_cleanups (back_to);
-
dont_repeat ();
}
struct trace_state_variable *tsv;
int ix;
int count = 0;
- struct cleanup *back_to;
struct ui_out *uiout = current_uiout;
if (VEC_length (tsv_s, tvariables) == 0 && !uiout->is_mi_like_p ())
tsv->value_known = target_get_trace_state_variable_value (tsv->number,
&(tsv->value));
- back_to = make_cleanup_ui_out_table_begin_end (uiout, 3,
- count, "trace-variables");
+ 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");
for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
{
- struct cleanup *back_to2;
const char *c;
- char *name;
- back_to2 = make_cleanup_ui_out_tuple_begin_end (uiout, "variable");
+ ui_out_emit_tuple tuple_emitter (uiout, "variable");
- name = concat ("$", tsv->name, (char *) NULL);
- make_cleanup (xfree, name);
- uiout->field_string ("name", name);
+ 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)
if (c)
uiout->field_string ("current", c);
uiout->text ("\n");
-
- do_cleanups (back_to2);
}
-
- do_cleanups (back_to);
}
/* List all the trace state variables. */
static void
-tvariables_info (char *args, int from_tty)
+info_tvariables_command (const char *args, int from_tty)
{
tvariables_info_1 ();
}
which is always an error. */
static void
-end_actions_pseudocommand (char *args, int from_tty)
+end_actions_pseudocommand (const char *args, int from_tty)
{
error (_("This command cannot be used at the top level."));
}
static void
-while_stepping_pseudocommand (char *args, int from_tty)
+while_stepping_pseudocommand (const char *args, int from_tty)
{
error (_("This command can only be used in a tracepoint actions list."));
}
static void
-collect_pseudocommand (char *args, int from_tty)
+collect_pseudocommand (const char *args, int from_tty)
{
error (_("This command can only be used in a tracepoint actions list."));
}
static void
-teval_pseudocommand (char *args, int from_tty)
+teval_pseudocommand (const char *args, int from_tty)
{
error (_("This command can only be used in a tracepoint actions list."));
}
else
error (_("Undefined collection format \"%c\"."), *exp);
- exp = skip_spaces_const (exp);
+ exp = skip_spaces (exp);
return exp;
}
/* Enter a list of actions for a tracepoint. */
static void
-actions_command (char *args, int from_tty)
+actions_command (const char *args, int from_tty)
{
struct tracepoint *t;
- struct command_line *l;
t = get_tracepoint_by_number (&args, NULL);
if (t)
{
- char *tmpbuf =
- xstrprintf ("Enter actions for tracepoint %d, one per line.",
- t->base.number);
- struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
-
- l = read_command_lines (tmpbuf, from_tty, 1,
- check_tracepoint_command, t);
- do_cleanups (cleanups);
- breakpoint_set_commands (&t->base, l);
+ std::string tmpbuf =
+ 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);
+ breakpoint_set_commands (t, std::move (l));
}
/* else just return */
}
validate_actionline (const char *line, struct breakpoint *b)
{
struct cmd_list_element *c;
- struct cleanup *old_chain = NULL;
const char *tmp_p;
const char *p;
struct bp_location *loc;
if (line == NULL)
return;
- p = skip_spaces_const (line);
+ p = skip_spaces (line);
/* Symbol lookup etc. */
if (*p == '\0') /* empty line: just prompt for another line. */
do
{ /* Repeat over a comma-separated list. */
QUIT; /* Allow user to bail out with ^C. */
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
if (*p == '$') /* Look for special pseudo-symbols. */
{
/* else fall thru, treat p as an expression and parse it! */
}
tmp_p = p;
- for (loc = t->base.loc; loc; loc = loc->next)
+ for (loc = t->loc; loc; loc = loc->next)
{
p = tmp_p;
expression_up exp = parse_exp_1 (&p, loc->address,
do
{ /* Repeat over a comma-separated list. */
QUIT; /* Allow user to bail out with ^C. */
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
tmp_p = p;
- for (loc = t->base.loc; loc; loc = loc->next)
+ for (loc = t->loc; loc; loc = loc->next)
{
p = tmp_p;
{
char *endp;
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
t->step_count = strtol (p, &endp, 0);
if (endp == p || t->step_count == 0)
error (_("while-stepping step count `%s' is malformed."), line);
/* Expressions are the most general case. */
if (treat_as_expr)
{
- struct cleanup *old_chain1 = NULL;
-
agent_expr_up aexpr = gen_trace_for_var (scope, gdbarch,
sym, trace_string);
/* Reduce a collection list to string form (for gdb protocol). */
-char **
+std::vector<std::string>
collection_list::stringify ()
{
char temp_buf[2048];
int count;
- int ndx = 0;
- char *(*str_list)[];
char *end;
long i;
-
- count = 1 + 1 + m_memranges.size () + m_aexprs.size () + 1;
- str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
+ std::vector<std::string> str_list;
if (m_strace_data)
{
printf_filtered ("\nCollecting static trace data\n");
end = temp_buf;
*end++ = 'L';
- (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
- ndx++;
+ str_list.emplace_back (temp_buf, end - temp_buf);
}
for (i = sizeof (m_regs_mask) - 1; i > 0; i--)
sprintf (end, "%02X", m_regs_mask[i]);
end += 2;
}
- (*str_list)[ndx] = xstrdup (temp_buf);
- ndx++;
+ str_list.emplace_back (temp_buf);
}
if (info_verbose)
printf_filtered ("\n");
}
if (count + 27 > MAX_AGENT_EXPR_LEN)
{
- (*str_list)[ndx] = savestring (temp_buf, count);
- ndx++;
+ str_list.emplace_back (temp_buf, count);
count = 0;
end = temp_buf;
}
QUIT; /* Allow user to bail out with ^C. */
if ((count + 10 + 2 * m_aexprs[i]->len) > MAX_AGENT_EXPR_LEN)
{
- (*str_list)[ndx] = savestring (temp_buf, count);
- ndx++;
+ str_list.emplace_back (temp_buf, count);
count = 0;
end = temp_buf;
}
if (count != 0)
{
- (*str_list)[ndx] = savestring (temp_buf, count);
- ndx++;
+ str_list.emplace_back (temp_buf, count);
count = 0;
end = temp_buf;
}
- (*str_list)[ndx] = NULL;
- if (ndx == 0)
- {
- xfree (str_list);
- return NULL;
- }
- else
- return *str_list;
+ return str_list;
}
/* Add the printed expression EXP to *LIST. */
{
QUIT; /* Allow user to bail out with ^C. */
action_exp = action->line;
- action_exp = skip_spaces_const (action_exp);
+ action_exp = skip_spaces (action_exp);
cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
if (cmd == 0)
do
{ /* Repeat over a comma-separated list. */
QUIT; /* Allow user to bail out with ^C. */
- action_exp = skip_spaces_const (action_exp);
+ action_exp = skip_spaces (action_exp);
if (0 == strncasecmp ("$reg", action_exp, 4))
{
else
{
unsigned long addr;
- struct cleanup *old_chain1 = NULL;
expression_up exp = parse_exp_1 (&action_exp, tloc->address,
block_for_pc (tloc->address),
do
{ /* Repeat over a comma-separated list. */
QUIT; /* Allow user to bail out with ^C. */
- action_exp = skip_spaces_const (action_exp);
+ action_exp = skip_spaces (action_exp);
{
- struct cleanup *old_chain1 = NULL;
-
expression_up exp = parse_exp_1 (&action_exp, tloc->address,
block_for_pc (tloc->address),
1);
/* Render all actions into gdb protocol. */
void
-encode_actions_rsp (struct bp_location *tloc, char ***tdp_actions,
- char ***stepping_actions)
+encode_actions_rsp (struct bp_location *tloc,
+ std::vector<std::string> *tdp_actions,
+ std::vector<std::string> *stepping_actions)
{
struct collection_list tracepoint_list, stepping_list;
- *tdp_actions = NULL;
- *stepping_actions = NULL;
-
encode_actions (tloc, &tracepoint_list, &stepping_list);
*tdp_actions = tracepoint_list.stringify ();
}
void
-start_tracing (char *notes)
+start_tracing (const char *notes)
{
VEC(breakpoint_p) *tp_vec = NULL;
int ix;
t->number_on_target = b->number;
for (loc = b->loc; loc; loc = loc->next)
- if (loc->probe.probe != NULL
- && loc->probe.probe->pops->set_semaphore != NULL)
- loc->probe.probe->pops->set_semaphore (loc->probe.probe,
- loc->probe.objfile,
- loc->gdbarch);
+ if (loc->probe.prob != NULL)
+ loc->probe.prob->set_semaphore (loc->probe.objfile,
+ loc->gdbarch);
if (bp_location_downloaded)
observer_notify_breakpoint_modified (b);
anybody else messing with the target. */
static void
-tstart_command (char *args, int from_tty)
+tstart_command (const char *args, int from_tty)
{
dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
of the trace run's status. */
static void
-tstop_command (char *args, int from_tty)
+tstop_command (const char *args, int from_tty)
{
if (!current_trace_status ()->running)
error (_("Trace is not running."));
}
void
-stop_tracing (char *note)
+stop_tracing (const char *note)
{
int ret;
VEC(breakpoint_p) *tp_vec = NULL;
but we don't really care if this semaphore goes out of sync.
That's why we are decrementing it here, but not taking care
in other places. */
- if (loc->probe.probe != NULL
- && loc->probe.probe->pops->clear_semaphore != NULL)
- loc->probe.probe->pops->clear_semaphore (loc->probe.probe,
- loc->probe.objfile,
- loc->gdbarch);
+ if (loc->probe.prob != NULL)
+ loc->probe.prob->clear_semaphore (loc->probe.objfile,
+ loc->gdbarch);
}
}
/* tstatus command */
static void
-tstatus_command (char *args, int from_tty)
+tstatus_command (const char *args, int from_tty)
{
struct trace_status *ts = current_trace_status ();
int status, ix;
reinit_frame_cache ();
target_dcache_invalidate ();
- set_tracepoint_num (tp ? tp->base.number : target_tracept);
+ set_tracepoint_num (tp ? tp->number : target_tracept);
if (target_frameno != get_traceframe_number ())
observer_notify_traceframe_changed (target_frameno, tracepoint_number);
}
static void
-tfind_command (char *args, int from_tty)
+tfind_command (const char *args, int from_tty)
{
- tfind_command_1 (const_cast<char *> (args), from_tty);
+ tfind_command_1 (args, from_tty);
}
/* tfind end */
static void
-tfind_end_command (char *args, int from_tty)
+tfind_end_command (const char *args, int from_tty)
{
tfind_command_1 ("-1", from_tty);
}
/* tfind start */
static void
-tfind_start_command (char *args, int from_tty)
+tfind_start_command (const char *args, int from_tty)
{
tfind_command_1 ("0", from_tty);
}
/* tfind pc command */
static void
-tfind_pc_command (char *args, int from_tty)
+tfind_pc_command (const char *args, int from_tty)
{
CORE_ADDR pc;
/* tfind tracepoint command */
static void
-tfind_tracepoint_command (char *args, int from_tty)
+tfind_tracepoint_command (const char *args, int from_tty)
{
int tdp;
struct tracepoint *tp;
corresponding to a source line OTHER THAN THE CURRENT ONE. */
static void
-tfind_line_command (char *args, int from_tty)
+tfind_line_command (const char *args, int from_tty)
{
- static CORE_ADDR start_pc, end_pc;
- struct symtabs_and_lines sals;
- struct symtab_and_line sal;
- struct cleanup *old_chain;
-
check_trace_running (current_trace_status ());
+ symtab_and_line sal;
if (args == 0 || *args == 0)
{
sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
- sals.nelts = 1;
- sals.sals = XNEW (struct symtab_and_line);
- sals.sals[0] = sal;
}
else
{
- sals = decode_line_with_current_source (args, DECODE_LINE_FUNFIRSTLINE);
- sal = sals.sals[0];
+ std::vector<symtab_and_line> sals
+ = decode_line_with_current_source (args, DECODE_LINE_FUNFIRSTLINE);
+ sal = sals[0];
}
-
- old_chain = make_cleanup (xfree, sals.sals);
+
if (sal.symtab == 0)
error (_("No line number information available."));
+ CORE_ADDR start_pc, end_pc;
if (sal.line > 0 && find_line_pc_range (sal, &start_pc, &end_pc))
{
if (start_pc == end_pc)
tfind_1 (tfind_range, 0, start_pc, end_pc - 1, from_tty);
else
tfind_1 (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
- do_cleanups (old_chain);
}
/* tfind range command */
static void
-tfind_range_command (char *args, int from_tty)
+tfind_range_command (const char *args, int from_tty)
{
static CORE_ADDR start, stop;
- char *tmp;
+ const char *tmp;
check_trace_running (current_trace_status ());
if (0 != (tmp = strchr (args, ',')))
{
- *tmp++ = '\0'; /* Terminate start address. */
+ std::string start_addr (args, tmp);
+ ++tmp;
tmp = skip_spaces (tmp);
- start = parse_and_eval_address (args);
+ start = parse_and_eval_address (start_addr.c_str ());
stop = parse_and_eval_address (tmp);
}
else
/* tfind outside command */
static void
-tfind_outside_command (char *args, int from_tty)
+tfind_outside_command (const char *args, int from_tty)
{
CORE_ADDR start, stop;
- char *tmp;
+ const char *tmp;
if (current_trace_status ()->running
&& current_trace_status ()->filename == NULL)
if (0 != (tmp = strchr (args, ',')))
{
- *tmp++ = '\0'; /* Terminate start address. */
+ std::string start_addr (args, tmp);
+ ++tmp;
tmp = skip_spaces (tmp);
- start = parse_and_eval_address (args);
+ start = parse_and_eval_address (start_addr.c_str ());
stop = parse_and_eval_address (tmp);
}
else
/* info scope command: list the locals for a scope. */
static void
-scope_info (char *args, int from_tty)
+info_scope_command (const char *args_in, int from_tty)
{
- struct symtabs_and_lines sals;
struct symbol *sym;
struct bound_minimal_symbol msym;
const struct block *block;
const char *symname;
- char *save_args = args;
+ const char *save_args = args_in;
struct block_iterator iter;
int j, count = 0;
struct gdbarch *gdbarch;
int regno;
+ const char *args = args_in;
if (args == 0 || *args == 0)
error (_("requires an argument (function, "
event_location_up location = string_to_event_location (&args,
current_language);
- sals = decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE,
- NULL, NULL, 0);
- if (sals.nelts == 0)
+ std::vector<symtab_and_line> sals
+ = decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE,
+ NULL, NULL, 0);
+ if (sals.empty ())
{
/* Presumably decode_line_1 has already warned. */
return;
}
/* Resolve line numbers to PC. */
- resolve_sal_pc (&sals.sals[0]);
- block = block_for_pc (sals.sals[0].pc);
+ resolve_sal_pc (&sals[0]);
+ block = block_for_pc (sals[0].pc);
while (block != 0)
{
QUIT; /* Allow user to bail out with ^C. */
action_exp = action->line;
- action_exp = skip_spaces_const (action_exp);
+ action_exp = skip_spaces (action_exp);
/* The collection actions to be done while stepping are
bracketed by the commands "while-stepping" and "end". */
QUIT; /* Allow user to bail out with ^C. */
if (*action_exp == ',')
action_exp++;
- action_exp = skip_spaces_const (action_exp);
+ action_exp = skip_spaces (action_exp);
next_comma = strchr (action_exp, ',');
else if (0 == strncasecmp (action_exp, "$_ret", 5))
;
else if (0 == strncasecmp (action_exp, "$loc", 4))
- locals_info (NULL, from_tty);
+ info_locals_command (NULL, from_tty);
else if (0 == strncasecmp (action_exp, "$arg", 4))
- args_info (NULL, from_tty);
+ info_args_command (NULL, from_tty);
else
{ /* variable */
if (next_comma != NULL)
locations, assume it is a direct hit rather than a while-stepping
frame. (FIXME this is not reliable, should record each frame's
type.) */
- for (tloc = t->base.loc; tloc; tloc = tloc->next)
+ for (tloc = t->loc; tloc; tloc = tloc->next)
if (tloc->address == regcache_read_pc (regcache))
{
*stepping_frame_p = 0;
/* If this is a stepping frame, we don't know which location
triggered. The first is as good (or bad) a guess as any... */
*stepping_frame_p = 1;
- return t->base.loc;
+ return t->loc;
}
/* Return all the actions, including default collect, of a tracepoint
/* The tdump command. */
static void
-tdump_command (char *args, int from_tty)
+tdump_command (const char *args, int from_tty)
{
int stepping_frame = 0;
struct bp_location *loc;
- struct cleanup *old_chain;
struct command_line *actions;
/* This throws an error is not inspecting a trace frame. */
/* This command only makes sense for the current frame, not the
selected frame. */
- old_chain = make_cleanup_restore_current_thread ();
+ scoped_restore_current_thread restore_thread;
+
select_frame (get_current_frame ());
actions = all_tracepoint_actions_and_cleanup (loc->owner);
trace_dump_actions (actions, 0, stepping_frame, from_tty);
-
- do_cleanups (old_chain);
}
/* Encode a piece of a tracepoint's source-level definition in a form
disconnects for some reason. */
static void
-set_disconnected_tracing (char *args, int from_tty,
+set_disconnected_tracing (const char *args, int from_tty,
struct cmd_list_element *c)
{
target_set_disconnected_tracing (disconnected_tracing);
}
static void
-set_circular_trace_buffer (char *args, int from_tty,
+set_circular_trace_buffer (const char *args, int from_tty,
struct cmd_list_element *c)
{
target_set_circular_trace_buffer (circular_trace_buffer);
}
static void
-set_trace_buffer_size (char *args, int from_tty,
+set_trace_buffer_size (const char *args, int from_tty,
struct cmd_list_element *c)
{
target_set_trace_buffer_size (trace_buffer_size);
}
static void
-set_trace_user (char *args, int from_tty,
+set_trace_user (const char *args, int from_tty,
struct cmd_list_element *c)
{
int ret;
}
static void
-set_trace_notes (char *args, int from_tty,
+set_trace_notes (const char *args, int from_tty,
struct cmd_list_element *c)
{
int ret;
}
static void
-set_trace_stop_notes (char *args, int from_tty,
+set_trace_stop_notes (const char *args, int from_tty,
struct cmd_list_element *c)
{
int ret;
if (b->type == utp->type
&& t->step_count == utp->step
&& t->pass_count == utp->pass
- && cond_string_is_same (t->base.cond_string, utp->cond_string)
+ && cond_string_is_same (t->cond_string, utp->cond_string)
/* FIXME also test actions. */
)
{
if (t)
printf_filtered (_("Created tracepoint %d for "
"target's tracepoint %d at %s.\n"),
- t->base.number, utp->number,
+ t->number, utp->number,
paddress (get_current_arch (), utp->addr));
else
printf_filtered (_("Failed to create tracepoint for target's "
create_tsv_from_upload (struct uploaded_tsv *utsv)
{
const char *namebase;
- char *buf;
+ std::string buf;
int try_num = 0;
struct trace_state_variable *tsv;
- struct cleanup *old_chain;
if (utsv->name)
{
namebase = utsv->name;
- buf = xstrprintf ("%s", namebase);
+ buf = namebase;
}
else
{
namebase = "__tsv";
- buf = xstrprintf ("%s_%d", namebase, try_num++);
+ buf = string_printf ("%s_%d", namebase, try_num++);
}
/* Fish for a name that is not in use. */
/* (should check against all internal vars?) */
- while (find_trace_state_variable (buf))
- {
- xfree (buf);
- buf = xstrprintf ("%s_%d", namebase, try_num++);
- }
-
- old_chain = make_cleanup (xfree, buf);
+ while (find_trace_state_variable (buf.c_str ()))
+ buf = string_printf ("%s_%d", namebase, try_num++);
/* We have an available name, create the variable. */
- tsv = create_trace_state_variable (buf);
+ tsv = create_trace_state_variable (buf.c_str ());
tsv->initial_value = utsv->initial_value;
tsv->builtin = utsv->builtin;
observer_notify_tsv_created (tsv);
- do_cleanups (old_chain);
-
return tsv;
}
the remote protocol and the trace file reader. */
void
-parse_trace_status (char *line, struct trace_status *ts)
+parse_trace_status (const char *line, struct trace_status *ts)
{
- char *p = line, *p1, *p2, *p3, *p_temp;
+ const char *p = line, *p1, *p2, *p3, *p_temp;
int end;
ULONGEST val;
}
void
-parse_tracepoint_status (char *p, struct breakpoint *bp,
+parse_tracepoint_status (const char *p, struct breakpoint *bp,
struct uploaded_tp *utp)
{
ULONGEST uval;
p = unpack_varlen_hex (p, &uval);
if (tp)
- tp->base.hit_count += uval;
+ tp->hit_count += uval;
else
utp->hit_count += uval;
p = unpack_varlen_hex (p + 1, &uval);
an "uploaded tracepoint". */
void
-parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
+parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp)
{
- char *p;
+ const char *p;
char piece;
ULONGEST num, addr, step, pass, orig_size, xlen, start;
int enabled, end;
enum bptype type;
- char *cond, *srctype, *buf;
+ const char *srctype;
+ char *cond, *buf;
struct uploaded_tp *utp = NULL;
p = line;
uploaded object. */
void
-parse_tsv_definition (char *line, struct uploaded_tsv **utsvp)
+parse_tsv_definition (const char *line, struct uploaded_tsv **utsvp)
{
- char *p, *buf;
+ const char *p;
+ char *buf;
ULONGEST num, initval, builtin;
int end;
struct uploaded_tsv *utsv = NULL;
the parsed marker definition. */
void
-parse_static_tracepoint_marker_definition (char *line, char **pp,
+parse_static_tracepoint_marker_definition (const char *line, const char **pp,
struct static_tracepoint_marker *marker)
{
- char *p, *endp;
+ const char *p, *endp;
ULONGEST addr;
int end;
char wrap_indent[80];
char extra_field_indent[80];
struct ui_out *uiout = current_uiout;
- struct cleanup *bkpt_chain;
VEC(breakpoint_p) *tracepoints;
- struct symtab_and_line sal;
-
- init_sal (&sal);
-
+ symtab_and_line sal;
sal.pc = marker->address;
tracepoints = static_tracepoints_here (marker->address);
- bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "marker");
+ ui_out_emit_tuple tuple_emitter (uiout, "marker");
/* A counter field to help readability. This is not a stable
identifier! */
if (!VEC_empty (breakpoint_p, tracepoints))
{
- struct cleanup *cleanup_chain;
int ix;
struct breakpoint *b;
- cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
- "tracepoints-at");
-
- uiout->text (extra_field_indent);
- uiout->text (_("Probed by static tracepoints: "));
- for (ix = 0; VEC_iterate(breakpoint_p, tracepoints, ix, b); ix++)
- {
- if (ix > 0)
- uiout->text (", ");
- uiout->text ("#");
- uiout->field_int ("tracepoint-id", b->number);
- }
+ {
+ ui_out_emit_tuple tuple_emitter (uiout, "tracepoints-at");
- do_cleanups (cleanup_chain);
+ uiout->text (extra_field_indent);
+ uiout->text (_("Probed by static tracepoints: "));
+ for (ix = 0; VEC_iterate(breakpoint_p, tracepoints, ix, b); ix++)
+ {
+ if (ix > 0)
+ uiout->text (", ");
+ uiout->text ("#");
+ uiout->field_int ("tracepoint-id", b->number);
+ }
+ }
if (uiout->is_mi_like_p ())
uiout->field_int ("number-of-tracepoints",
uiout->text ("\n");
}
VEC_free (breakpoint_p, tracepoints);
-
- do_cleanups (bkpt_chain);
}
static void
-info_static_tracepoint_markers_command (char *arg, int from_tty)
+info_static_tracepoint_markers_command (const char *arg, int from_tty)
{
VEC(static_tracepoint_marker_p) *markers;
struct cleanup *old_chain;
don't work without in-process agent, so we don't bother users to type
`set agent on' when to use static tracepoint. */
- old_chain
- = make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
- "StaticTracepointMarkersTable");
+ ui_out_emit_table table_emitter (uiout, 5, -1,
+ "StaticTracepointMarkersTable");
uiout->table_header (7, ui_left, "counter", "Cnt");
uiout->table_body ();
markers = target_static_tracepoint_markers_by_strid (NULL);
- make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers);
+ old_chain = make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers);
for (i = 0;
VEC_iterate (static_tracepoint_marker_p,
#if !defined(HAVE_LIBEXPAT)
-struct traceframe_info *
+struct std::unique_ptr<traceframe_info>
parse_traceframe_info (const char *tframe_info)
{
static int have_warned;
static void
traceframe_info_start_memory (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
- void *user_data, VEC(gdb_xml_value_s) *attributes)
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
{
struct traceframe_info *info = (struct traceframe_info *) user_data;
- struct mem_range *r = VEC_safe_push (mem_range_s, info->memory, NULL);
ULONGEST *start_p, *length_p;
start_p
- = (ULONGEST *) xml_find_attribute (attributes, "start")->value;
+ = (ULONGEST *) xml_find_attribute (attributes, "start")->value.get ();
length_p
- = (ULONGEST *) xml_find_attribute (attributes, "length")->value;
+ = (ULONGEST *) xml_find_attribute (attributes, "length")->value.get ();
- r->start = *start_p;
- r->length = *length_p;
+ info->memory.emplace_back (*start_p, *length_p);
}
/* Handle the start of a <tvar> element. */
traceframe_info_start_tvar (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data,
- VEC(gdb_xml_value_s) *attributes)
+ std::vector<gdb_xml_value> &attributes)
{
struct traceframe_info *info = (struct traceframe_info *) user_data;
const char *id_attrib
- = (const char *) xml_find_attribute (attributes, "id")->value;
+ = (const char *) xml_find_attribute (attributes, "id")->value.get ();
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
-free_result (void *p)
-{
- struct traceframe_info *result = (struct traceframe_info *) p;
-
- free_traceframe_info (result);
+ info->tvars.push_back (id);
}
/* The allowed elements and attributes for an XML memory map. */
/* Parse a traceframe-info XML document. */
-struct traceframe_info *
+traceframe_info_up
parse_traceframe_info (const char *tframe_info)
{
- struct traceframe_info *result;
- struct cleanup *back_to;
-
- result = XCNEW (struct traceframe_info);
- back_to = make_cleanup (free_result, result);
+ traceframe_info_up result (new traceframe_info);
if (gdb_xml_parse_quick (_("trace frame info"),
"traceframe-info.dtd", traceframe_info_elements,
- tframe_info, result) == 0)
- {
- /* Parsed successfully, keep the result. */
- discard_cleanups (back_to);
-
- return result;
- }
+ tframe_info, result.get ()) == 0)
+ return result;
- do_cleanups (back_to);
return NULL;
}
struct traceframe_info *
get_traceframe_info (void)
{
- if (traceframe_info == NULL)
- traceframe_info = target_traceframe_info ();
+ if (current_traceframe_info == NULL)
+ current_traceframe_info = target_traceframe_info ();
- return traceframe_info;
+ return current_traceframe_info.get ();
}
/* If the target supports the query, return in RESULT the set of
undefined. */
int
-traceframe_available_memory (VEC(mem_range_s) **result,
+traceframe_available_memory (std::vector<mem_range> *result,
CORE_ADDR memaddr, ULONGEST len)
{
struct traceframe_info *info = get_traceframe_info ();
if (info != NULL)
{
- struct mem_range *r;
- int i;
-
- *result = NULL;
+ result->clear ();
- for (i = 0; VEC_iterate (mem_range_s, info->memory, i, r); i++)
- if (mem_ranges_overlap (r->start, r->length, memaddr, len))
+ for (mem_range &r : info->memory)
+ if (mem_ranges_overlap (r.start, r.length, memaddr, len))
{
ULONGEST lo1, hi1, lo2, hi2;
- struct mem_range *nr;
lo1 = memaddr;
hi1 = memaddr + len;
- lo2 = r->start;
- hi2 = r->start + r->length;
+ lo2 = r.start;
+ hi2 = r.start + r.length;
- nr = VEC_safe_push (mem_range_s, *result, NULL);
+ CORE_ADDR start = std::max (lo1, lo2);
+ int length = std::min (hi1, hi2) - start;
- nr->start = std::max (lo1, lo2);
- nr->length = std::min (hi1, hi2) - nr->start;
+ result->emplace_back (start, length);
}
- normalize_mem_ranges (*result);
+ normalize_mem_ranges (result);
return 1;
}
traceframe_number = -1;
tracepoint_number = -1;
- add_info ("scope", scope_info,
+ add_info ("scope", info_scope_command,
_("List the variables local to a scope"));
- add_cmd ("tracepoints", class_trace, NULL,
+ add_cmd ("tracepoints", class_trace,
_("Tracing of program execution without stopping the program."),
&cmdlist);
If no arguments are supplied, delete all variables."), &deletelist);
/* FIXME add a trace variable completer. */
- add_info ("tvariables", tvariables_info, _("\
+ add_info ("tvariables", info_tvariables_command, _("\
Status of trace state variables and their values.\n\
"));