/* Tracing functionality for remote targets in custom GDB protocol
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "completer.h"
#include "block.h"
#include "dictionary.h"
-#include "observer.h"
+#include "observable.h"
#include "user-regs.h"
#include "valprint.h"
#include "gdbcore.h"
#include "memrange.h"
#include "cli/cli-utils.h"
#include "probe.h"
-#include "ctf.h"
-#include "filestuff.h"
-#include "rsp-low.h"
+#include "gdbsupport/filestuff.h"
+#include "gdbsupport/rsp-low.h"
#include "tracefile.h"
#include "location.h"
#include <algorithm>
-
-/* readline include files */
-#include "readline/readline.h"
-#include "readline/history.h"
-
-/* readline defines this. */
-#undef savestring
+#include "cli/cli-style.h"
#include <unistd.h>
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. */
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;
/* List of expressions to collect by default at each tracepoint hit. */
-char *default_collect = "";
+char *default_collect;
-static int disconnected_tracing;
+static bool disconnected_tracing;
/* This variable controls whether we ask the target for a linear or
circular trace buffer. */
-static int circular_trace_buffer;
+static bool circular_trace_buffer;
/* This variable is the requested trace buffer size, or -1 to indicate
that we don't care and leave it up to the target to set a size. */
char *trace_stop_notes = NULL;
-/* ======= Important command functions: ======= */
-static void trace_actions_command (char *, int);
-static void trace_start_command (char *, int);
-static void trace_stop_command (char *, int);
-static void trace_status_command (char *, int);
-static void trace_find_command (char *, int);
-static void trace_find_pc_command (char *, int);
-static void trace_find_tracepoint_command (char *, int);
-static void trace_find_line_command (char *, int);
-static void trace_find_range_command (char *, int);
-static void trace_find_outside_command (char *, int);
-static void trace_dump_command (char *, int);
-
/* support routines */
struct collection_list;
static char *mem2hex (gdb_byte *, char *, int);
-static struct command_line *
- all_tracepoint_actions_and_cleanup (struct breakpoint *t);
-
-extern void _initialize_tracepoint (void);
+static counted_command_line all_tracepoint_actions (struct breakpoint *);
static struct trace_status trace_status;
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);
}
/* Save func name as "$trace_func", a debugger variable visible to
users. */
if (traceframe_fun == NULL
- || SYMBOL_LINKAGE_NAME (traceframe_fun) == NULL)
+ || traceframe_fun->linkage_name () == NULL)
clear_internalvar (lookup_internalvar ("trace_func"));
else
set_internalvar_string (lookup_internalvar ("trace_func"),
- SYMBOL_LINKAGE_NAME (traceframe_fun));
+ traceframe_fun->linkage_name ());
/* Save file name as "$trace_file", a debugger variable visible to
users. */
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)
{
- observer_notify_tsv_deleted (tsv);
-
- xfree ((void *)tsv->name);
- VEC_unordered_remove (tsv_s, tvariables, ix);
-
+ gdb::observers::tsv_deleted.notify (&*it);
+ tvariables.erase (it);
return;
}
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)
{
tsv->initial_value = initval;
- observer_notify_tsv_modified (tsv);
+ gdb::observers::tsv_modified.notify (tsv);
}
printf_filtered (_("Trace state variable $%s "
"now has initial value %s.\n"),
- tsv->name, plongest (tsv->initial_value));
- do_cleanups (old_chain);
+ tsv->name.c_str (), plongest (tsv->initial_value));
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);
+ gdb::observers::tsv_created.notify (tsv);
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
- tsv->name, plongest (tsv->initial_value));
-
- do_cleanups (old_chain);
+ tsv->name.c_str (), plongest (tsv->initial_value));
}
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? ")))
- VEC_free (tsv_s, tvariables);
+ tvariables.clear ();
dont_repeat ();
- observer_notify_tsv_deleted (NULL);
+ gdb::observers::tsv_deleted.notify (NULL);
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 ();
}
void
tvariables_info_1 (void)
{
- 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 && !ui_out_is_mi_like_p (uiout))
- {
- 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);
- back_to = make_cleanup_ui_out_table_begin_end (uiout, 3,
- count, "trace-variables");
- ui_out_table_header (uiout, 15, ui_left, "name", "Name");
- ui_out_table_header (uiout, 11, ui_left, "initial", "Initial");
- ui_out_table_header (uiout, 11, ui_left, "current", "Current");
-
- ui_out_table_body (uiout);
+ {
+ 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");
- for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
- {
- struct cleanup *back_to2;
- char *c;
- char *name;
-
- back_to2 = make_cleanup_ui_out_tuple_begin_end (uiout, "variable");
-
- name = concat ("$", tsv->name, (char *) NULL);
- make_cleanup (xfree, name);
- ui_out_field_string (uiout, "name", name);
- ui_out_field_string (uiout, "initial", plongest (tsv->initial_value));
-
- if (tsv->value_known)
- c = plongest (tsv->value);
- else if (ui_out_is_mi_like_p (uiout))
- /* 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)
- ui_out_field_string (uiout, "current", c);
- ui_out_text (uiout, "\n");
+ uiout->table_body ();
- do_cleanups (back_to2);
- }
+ 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));
+
+ ui_file_style style;
+ 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>";
+ style = metadata_style.style ();
+ }
+ else
+ {
+ /* It is not meaningful to ask about the value. */
+ c = "<undefined>";
+ style = metadata_style.style ();
+ }
+ if (c)
+ uiout->field_string ("current", c, style);
+ uiout->text ("\n");
+ }
+ }
- do_cleanups (back_to);
+ if (tvariables.empty ())
+ uiout->text (_("No trace state variables.\n"));
}
/* 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 ();
}
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");
}
}
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
-trace_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);
+
+ counted_command_line l = read_command_lines (tmpbuf.c_str (),
+ from_tty, 1,
+ [=] (const char *line)
+ {
+ validate_actionline (line, t);
+ });
+ breakpoint_set_commands (t, std::move (l));
}
/* else just return */
}
error (_("Expression is too complicated."));
}
+/* Call ax_reqs on AEXPR and raise an error if something is wrong. */
+
+static void
+finalize_tracepoint_aexpr (struct agent_expr *aexpr)
+{
+ ax_reqs (aexpr);
+
+ if (aexpr->len > MAX_AGENT_EXPR_LEN)
+ error (_("Expression is too complicated."));
+
+ report_agent_reqs_errors (aexpr);
+}
+
/* worker function */
void
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;
- struct agent_expr *aexpr;
struct tracepoint *t = (struct tracepoint *) b;
/* If EOF is typed, *line is NULL. */
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,
{
error (_("constant `%s' (value %s) "
"will not be collected."),
- SYMBOL_PRINT_NAME (exp->elts[2].symbol),
+ exp->elts[2].symbol->print_name (),
plongest (SYMBOL_VALUE (exp->elts[2].symbol)));
}
else if (SYMBOL_CLASS (exp->elts[2].symbol)
{
error (_("`%s' is optimized away "
"and cannot be collected."),
- SYMBOL_PRINT_NAME (exp->elts[2].symbol));
+ exp->elts[2].symbol->print_name ());
}
}
/* We have something to collect, make sure that the expr to
bytecode translator can handle it and that it's not too
long. */
- aexpr = gen_trace_for_expr (loc->address, exp.get (), trace_string);
- old_chain = make_cleanup_free_agent_expr (aexpr);
-
- if (aexpr->len > MAX_AGENT_EXPR_LEN)
- error (_("Expression is too complicated."));
-
- ax_reqs (aexpr);
-
- report_agent_reqs_errors (aexpr);
+ agent_expr_up aexpr = gen_trace_for_expr (loc->address,
+ exp.get (),
+ trace_string);
- do_cleanups (old_chain);
+ finalize_tracepoint_aexpr (aexpr.get ());
}
}
while (p && *p++ == ',');
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;
/* We have something to evaluate, make sure that the expr to
bytecode translator can handle it and that it's not too
long. */
- aexpr = gen_eval_for_expr (loc->address, exp.get ());
- old_chain = make_cleanup_free_agent_expr (aexpr);
-
- if (aexpr->len > MAX_AGENT_EXPR_LEN)
- error (_("Expression is too complicated."));
-
- ax_reqs (aexpr);
- report_agent_reqs_errors (aexpr);
+ agent_expr_up aexpr = gen_eval_for_expr (loc->address, exp.get ());
- do_cleanups (old_chain);
+ finalize_tracepoint_aexpr (aexpr.get ());
}
}
while (p && *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);
}
}
-/* Add a register to a collection list. */
+/* Add remote register number REGNO to the collection list mask. */
void
-collection_list::add_register (unsigned int regno)
+collection_list::add_remote_register (unsigned int regno)
{
if (info_verbose)
printf_filtered ("collect register %d\n", regno);
- if (regno >= (8 * sizeof (m_regs_mask)))
- error (_("Internal: register number %d too large for tracepoint"),
- regno);
- m_regs_mask[regno / 8] |= 1 << (regno % 8);
+
+ m_regs_mask.at (regno / 8) |= 1 << (regno % 8);
}
-/* Add a memrange to a collection list. */
+/* Add all the registers from the mask in AEXPR to the mask in the
+ collection list. Registers in the AEXPR mask are already remote
+ register numbers. */
void
-collection_list::add_memrange (int type, bfd_signed_vma base,
- unsigned long len)
+collection_list::add_ax_registers (struct agent_expr *aexpr)
{
- if (info_verbose)
+ if (aexpr->reg_mask_len > 0)
{
- printf_filtered ("(%d,", type);
- printf_vma (base);
- printf_filtered (",%ld)\n", len);
+ for (int ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
+ {
+ QUIT; /* Allow user to bail out with ^C. */
+ if (aexpr->reg_mask[ndx1] != 0)
+ {
+ /* Assume chars have 8 bits. */
+ for (int ndx2 = 0; ndx2 < 8; ndx2++)
+ if (aexpr->reg_mask[ndx1] & (1 << ndx2))
+ /* It's used -- record it. */
+ add_remote_register (ndx1 * 8 + ndx2);
+ }
+ }
+ }
+}
+
+/* If REGNO is raw, add its corresponding remote register number to
+ the mask. If REGNO is a pseudo-register, figure out the necessary
+ registers using a temporary agent expression, and add it to the
+ list if it needs more than just a mask. */
+
+void
+collection_list::add_local_register (struct gdbarch *gdbarch,
+ unsigned int regno,
+ CORE_ADDR scope)
+{
+ if (regno < gdbarch_num_regs (gdbarch))
+ {
+ int remote_regno = gdbarch_remote_register_number (gdbarch, regno);
+
+ if (remote_regno < 0)
+ error (_("Can't collect register %d"), regno);
+
+ add_remote_register (remote_regno);
}
+ else
+ {
+ agent_expr_up aexpr (new agent_expr (gdbarch, scope));
+
+ ax_reg_mask (aexpr.get (), regno);
+
+ finalize_tracepoint_aexpr (aexpr.get ());
+
+ add_ax_registers (aexpr.get ());
+
+ /* Usually ax_reg_mask for a pseudo-regiser only sets the
+ corresponding raw registers in the ax mask, but if this isn't
+ the case add the expression that is generated to the
+ collection list. */
+ if (aexpr->len > 0)
+ add_aexpr (std::move (aexpr));
+ }
+}
+
+/* Add a memrange to a collection list. */
+
+void
+collection_list::add_memrange (struct gdbarch *gdbarch,
+ int type, bfd_signed_vma base,
+ unsigned long len, CORE_ADDR scope)
+{
+ if (info_verbose)
+ printf_filtered ("(%d,%s,%ld)\n", type, paddress (gdbarch, base), len);
/* type: memrange_absolute == memory, other n == basereg */
/* base: addr if memory, offset if reg relative. */
/* len: we actually save end (base + len) for convenience */
- m_memranges.push_back (memrange (type, base, base + len));
+ m_memranges.emplace_back (type, base, base + len);
if (type != memrange_absolute) /* Better collect the base register! */
- add_register (type);
+ add_local_register (gdbarch, type, scope);
}
/* Add a symbol to a collection list. */
{
default:
printf_filtered ("%s: don't know symbol class %d\n",
- SYMBOL_PRINT_NAME (sym),
- SYMBOL_CLASS (sym));
+ sym->print_name (), SYMBOL_CLASS (sym));
break;
case LOC_CONST:
printf_filtered ("constant %s (value %s) will not be collected.\n",
- SYMBOL_PRINT_NAME (sym), plongest (SYMBOL_VALUE (sym)));
+ sym->print_name (), plongest (SYMBOL_VALUE (sym)));
break;
case LOC_STATIC:
offset = SYMBOL_VALUE_ADDRESS (sym);
if (info_verbose)
{
- char tmp[40];
-
- sprintf_vma (tmp, offset);
printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
- SYMBOL_PRINT_NAME (sym), len,
- tmp /* address */);
+ sym->print_name (), len,
+ paddress (gdbarch, offset));
}
/* A struct may be a C++ class with static fields, go to general
expression handling. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
treat_as_expr = 1;
else
- add_memrange (memrange_absolute, offset, len);
+ add_memrange (gdbarch, memrange_absolute, offset, len, scope);
break;
case LOC_REGISTER:
reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
if (info_verbose)
- printf_filtered ("LOC_REG[parm] %s: ",
- SYMBOL_PRINT_NAME (sym));
- add_register (reg);
+ printf_filtered ("LOC_REG[parm] %s: ", sym->print_name ());
+ add_local_register (gdbarch, reg, scope);
/* Check for doubles stored in two registers. */
/* FIXME: how about larger types stored in 3 or more regs? */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
len > register_size (gdbarch, reg))
- add_register (reg + 1);
+ add_local_register (gdbarch, reg + 1, scope);
break;
case LOC_REF_ARG:
printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
- printf_filtered (" (will not collect %s)\n",
- SYMBOL_PRINT_NAME (sym));
+ printf_filtered (" (will not collect %s)\n", sym->print_name ());
break;
case LOC_ARG:
reg = frame_regno;
offset = frame_offset + SYMBOL_VALUE (sym);
if (info_verbose)
{
- printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
- SYMBOL_PRINT_NAME (sym), len);
- printf_vma (offset);
- printf_filtered (" from frame ptr reg %d\n", reg);
+ printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset %s"
+ " from frame ptr reg %d\n", sym->print_name (), len,
+ paddress (gdbarch, offset), reg);
}
- add_memrange (reg, offset, len);
+ add_memrange (gdbarch, reg, offset, len, scope);
break;
case LOC_REGPARM_ADDR:
reg = SYMBOL_VALUE (sym);
offset = 0;
if (info_verbose)
{
- printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
- SYMBOL_PRINT_NAME (sym), len);
- printf_vma (offset);
- printf_filtered (" from reg %d\n", reg);
+ printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset %s"
+ " from reg %d\n", sym->print_name (), len,
+ paddress (gdbarch, offset), reg);
}
- add_memrange (reg, offset, len);
+ add_memrange (gdbarch, reg, offset, len, scope);
break;
case LOC_LOCAL:
reg = frame_regno;
offset = frame_offset + SYMBOL_VALUE (sym);
if (info_verbose)
{
- printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
- SYMBOL_PRINT_NAME (sym), len);
- printf_vma (offset);
- printf_filtered (" from frame ptr reg %d\n", reg);
+ printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset %s"
+ " from frame ptr reg %d\n", sym->print_name (), len,
+ paddress (gdbarch, offset), reg);
}
- add_memrange (reg, offset, len);
+ add_memrange (gdbarch, reg, offset, len, scope);
break;
case LOC_UNRESOLVED:
case LOC_OPTIMIZED_OUT:
printf_filtered ("%s has been optimized out of existence.\n",
- SYMBOL_PRINT_NAME (sym));
+ sym->print_name ());
break;
case LOC_COMPUTED:
/* Expressions are the most general case. */
if (treat_as_expr)
{
- struct agent_expr *aexpr;
- struct cleanup *old_chain1 = NULL;
-
- aexpr = gen_trace_for_var (scope, gdbarch, sym, trace_string);
+ agent_expr_up aexpr = gen_trace_for_var (scope, gdbarch,
+ sym, trace_string);
/* It can happen that the symbol is recorded as a computed
location, but it's been optimized away and doesn't actually
if (!aexpr)
{
printf_filtered ("%s has been optimized out of existence.\n",
- SYMBOL_PRINT_NAME (sym));
+ sym->print_name ());
return;
}
- old_chain1 = make_cleanup_free_agent_expr (aexpr);
-
- ax_reqs (aexpr);
-
- report_agent_reqs_errors (aexpr);
-
- discard_cleanups (old_chain1);
- add_aexpr (aexpr);
+ finalize_tracepoint_aexpr (aexpr.get ());
/* Take care of the registers. */
- if (aexpr->reg_mask_len > 0)
- {
- int ndx1, ndx2;
+ add_ax_registers (aexpr.get ());
- for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
- {
- QUIT; /* Allow user to bail out with ^C. */
- if (aexpr->reg_mask[ndx1] != 0)
- {
- /* Assume chars have 8 bits. */
- for (ndx2 = 0; ndx2 < 8; ndx2++)
- if (aexpr->reg_mask[ndx1] & (1 << ndx2))
- /* It's used -- record it. */
- add_register (ndx1 * 8 + ndx2);
- }
- }
- }
+ add_aexpr (std::move (aexpr));
}
}
}
collection_list::collection_list ()
- : m_regs_mask (),
- m_strace_data (false)
+ : m_strace_data (false)
{
+ int max_remote_regno = 0;
+ for (int i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
+ {
+ int remote_regno = (gdbarch_remote_register_number
+ (target_gdbarch (), i));
+
+ if (remote_regno >= 0 && remote_regno > max_remote_regno)
+ max_remote_regno = remote_regno;
+ }
+
+ m_regs_mask.resize ((max_remote_regno / 8) + 1);
+
m_memranges.reserve (128);
m_aexprs.reserve (128);
}
-collection_list::~collection_list ()
-{
- for (int ndx = 0; ndx < m_aexprs.size (); ndx++)
- free_agent_expr (m_aexprs[ndx]);
-}
-
/* Reduce a collection list to string form (for gdb protocol). */
-char **
+std::vector<std::string>
collection_list::stringify ()
{
- char temp_buf[2048];
- char tmp2[40];
+ gdb::char_vector 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)
{
if (info_verbose)
printf_filtered ("\nCollecting static trace data\n");
- end = temp_buf;
+ end = temp_buf.data ();
*end++ = 'L';
- (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
- ndx++;
+ str_list.emplace_back (temp_buf.data (), end - temp_buf.data ());
}
- for (i = sizeof (m_regs_mask) - 1; i > 0; i--)
+ for (i = m_regs_mask.size () - 1; i > 0; i--)
if (m_regs_mask[i] != 0) /* Skip leading zeroes in regs_mask. */
break;
if (m_regs_mask[i] != 0) /* Prepare to send regs_mask to the stub. */
{
if (info_verbose)
printf_filtered ("\nCollecting registers (mask): 0x");
- end = temp_buf;
+
+ /* One char for 'R', one for the null terminator and two per
+ mask byte. */
+ std::size_t new_size = (i + 1) * 2 + 2;
+ if (new_size > temp_buf.size ())
+ temp_buf.resize (new_size);
+
+ end = temp_buf.data ();
*end++ = 'R';
for (; i >= 0; i--)
{
QUIT; /* Allow user to bail out with ^C. */
if (info_verbose)
printf_filtered ("%02X", m_regs_mask[i]);
- sprintf (end, "%02X", m_regs_mask[i]);
- end += 2;
+
+ end = pack_hex_byte (end, m_regs_mask[i]);
}
- (*str_list)[ndx] = xstrdup (temp_buf);
- ndx++;
+ *end = '\0';
+
+ str_list.emplace_back (temp_buf.data ());
}
if (info_verbose)
printf_filtered ("\n");
if (!m_memranges.empty () && info_verbose)
printf_filtered ("Collecting memranges: \n");
- for (i = 0, count = 0, end = temp_buf; i < m_memranges.size (); i++)
+ for (i = 0, count = 0, end = temp_buf.data ();
+ i < m_memranges.size (); i++)
{
QUIT; /* Allow user to bail out with ^C. */
- sprintf_vma (tmp2, m_memranges[i].start);
if (info_verbose)
{
printf_filtered ("(%d, %s, %ld)\n",
m_memranges[i].type,
- tmp2,
+ paddress (target_gdbarch (),
+ m_memranges[i].start),
(long) (m_memranges[i].end
- m_memranges[i].start));
}
if (count + 27 > MAX_AGENT_EXPR_LEN)
{
- (*str_list)[ndx] = savestring (temp_buf, count);
- ndx++;
+ str_list.emplace_back (temp_buf.data (), count);
count = 0;
- end = temp_buf;
+ end = temp_buf.data ();
}
{
"FFFFFFFF" (or more, depending on sizeof (unsigned)).
Special-case it. */
if (m_memranges[i].type == memrange_absolute)
- sprintf (end, "M-1,%s,%lX", tmp2, (long) length);
+ sprintf (end, "M-1,%s,%lX", phex_nz (m_memranges[i].start, 0),
+ (long) length);
else
- sprintf (end, "M%X,%s,%lX", m_memranges[i].type, tmp2, (long) length);
+ sprintf (end, "M%X,%s,%lX", m_memranges[i].type,
+ phex_nz (m_memranges[i].start, 0), (long) length);
}
count += strlen (end);
- end = temp_buf + count;
+ end = temp_buf.data () + count;
}
for (i = 0; i < m_aexprs.size (); i++)
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.data (), count);
count = 0;
- end = temp_buf;
+ end = temp_buf.data ();
}
sprintf (end, "X%08X,", m_aexprs[i]->len);
end += 10; /* 'X' + 8 hex digits + ',' */
if (count != 0)
{
- (*str_list)[ndx] = savestring (temp_buf, count);
- ndx++;
+ str_list.emplace_back (temp_buf.data (), count);
count = 0;
- end = temp_buf;
+ end = temp_buf.data ();
}
- (*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. */
void
collection_list::append_exp (struct expression *exp)
{
- struct ui_file *tmp_stream = mem_fileopen ();
+ string_file tmp_stream;
- print_expression (exp, tmp_stream);
+ print_expression (exp, &tmp_stream);
- m_computed.push_back (ui_file_as_string (tmp_stream));
- ui_file_delete (tmp_stream);
+ m_computed.push_back (std::move (tmp_stream.string ()));
}
void
int i;
struct value *tempval;
struct cmd_list_element *cmd;
- struct agent_expr *aexpr;
for (; action; action = action->next)
{
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))
{
- for (i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
- collect->add_register (i);
+ for (i = 0; i < gdbarch_num_regs (target_gdbarch ());
+ i++)
+ {
+ int remote_regno = (gdbarch_remote_register_number
+ (target_gdbarch (), i));
+
+ /* Ignore arch regnos without a corresponding
+ remote regno. This can happen for regnos not
+ in the tdesc. */
+ if (remote_regno >= 0)
+ collect->add_remote_register (remote_regno);
+ }
action_exp = strchr (action_exp, ','); /* more? */
}
else if (0 == strncasecmp ("$arg", action_exp, 4))
}
else if (0 == strncasecmp ("$_ret", action_exp, 5))
{
- struct cleanup *old_chain1 = NULL;
-
- aexpr = gen_trace_for_return_address (tloc->address,
- target_gdbarch (),
- trace_string);
-
- old_chain1 = make_cleanup_free_agent_expr (aexpr);
-
- ax_reqs (aexpr);
- report_agent_reqs_errors (aexpr);
+ agent_expr_up aexpr
+ = gen_trace_for_return_address (tloc->address,
+ target_gdbarch (),
+ trace_string);
- discard_cleanups (old_chain1);
- collect->add_aexpr (aexpr);
+ finalize_tracepoint_aexpr (aexpr.get ());
/* take care of the registers */
- if (aexpr->reg_mask_len > 0)
- {
- int ndx1, ndx2;
-
- for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
- {
- QUIT; /* allow user to bail out with ^C */
- if (aexpr->reg_mask[ndx1] != 0)
- {
- /* assume chars have 8 bits */
- for (ndx2 = 0; ndx2 < 8; ndx2++)
- if (aexpr->reg_mask[ndx1] & (1 << ndx2))
- {
- /* It's used -- record it. */
- collect->add_register (ndx1 * 8 + ndx2);
- }
- }
- }
- }
+ collect->add_ax_registers (aexpr.get ());
+ collect->add_aexpr (std::move (aexpr));
action_exp = strchr (action_exp, ','); /* more? */
}
else if (0 == strncasecmp ("$_sdata", action_exp, 7))
else
{
unsigned long addr;
- struct cleanup *old_chain1 = NULL;
expression_up exp = parse_exp_1 (&action_exp, tloc->address,
block_for_pc (tloc->address),
name);
if (info_verbose)
printf_filtered ("OP_REGISTER: ");
- collect->add_register (i);
+ collect->add_local_register (target_gdbarch (),
+ i, tloc->address);
break;
}
addr = value_address (tempval);
/* Initialize the TYPE_LENGTH if it is a typedef. */
check_typedef (exp->elts[1].type);
- collect->add_memrange (memrange_absolute, addr,
- TYPE_LENGTH (exp->elts[1].type));
+ collect->add_memrange (target_gdbarch (),
+ memrange_absolute, addr,
+ TYPE_LENGTH (exp->elts[1].type),
+ tloc->address);
collect->append_exp (exp.get ());
break;
case OP_VAR_VALUE:
{
struct symbol *sym = exp->elts[2].symbol;
- char_ptr name = (char_ptr) SYMBOL_NATURAL_NAME (sym);
+ const char *name = sym->natural_name ();
collect->collect_symbol (exp->elts[2].symbol,
target_gdbarch (),
break;
default: /* Full-fledged expression. */
- aexpr = gen_trace_for_expr (tloc->address, exp.get (),
- trace_string);
-
- old_chain1 = make_cleanup_free_agent_expr (aexpr);
-
- ax_reqs (aexpr);
-
- report_agent_reqs_errors (aexpr);
+ agent_expr_up aexpr = gen_trace_for_expr (tloc->address,
+ exp.get (),
+ trace_string);
- discard_cleanups (old_chain1);
- collect->add_aexpr (aexpr);
+ finalize_tracepoint_aexpr (aexpr.get ());
/* Take care of the registers. */
- if (aexpr->reg_mask_len > 0)
- {
- int ndx1;
- int ndx2;
-
- for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
- {
- QUIT; /* Allow user to bail out with ^C. */
- if (aexpr->reg_mask[ndx1] != 0)
- {
- /* Assume chars have 8 bits. */
- for (ndx2 = 0; ndx2 < 8; ndx2++)
- if (aexpr->reg_mask[ndx1] & (1 << ndx2))
- {
- /* It's used -- record it. */
- collect->add_register (ndx1 * 8 + ndx2);
- }
- }
- }
- }
+ collect->add_ax_registers (aexpr.get ());
+ collect->add_aexpr (std::move (aexpr));
collect->append_exp (exp.get ());
break;
} /* switch */
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);
- aexpr = gen_eval_for_expr (tloc->address, exp.get ());
- old_chain1 = make_cleanup_free_agent_expr (aexpr);
+ agent_expr_up aexpr = gen_eval_for_expr (tloc->address,
+ exp.get ());
- ax_reqs (aexpr);
- report_agent_reqs_errors (aexpr);
+ finalize_tracepoint_aexpr (aexpr.get ());
- discard_cleanups (old_chain1);
/* Even though we're not officially collecting, add
to the collect list anyway. */
- collect->add_aexpr (aexpr);
+ collect->add_aexpr (std::move (aexpr));
} /* do */
}
while (action_exp && *action_exp++ == ',');
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 ();
/* 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
-collection_list::add_aexpr (struct agent_expr *aexpr)
+collection_list::add_aexpr (agent_expr_up aexpr)
{
- m_aexprs.push_back (aexpr);
+ m_aexprs.push_back (std::move (aexpr));
}
static void
process_tracepoint_on_disconnect (void)
{
- VEC(breakpoint_p) *tp_vec = NULL;
- int ix;
- struct breakpoint *b;
int has_pending_p = 0;
/* Check whether we still have pending tracepoint. If we have, warn the
user that pending tracepoint will no longer work. */
- tp_vec = all_tracepoints ();
- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
+ for (breakpoint *b : all_tracepoints ())
{
if (b->loc == NULL)
{
break;
}
}
- VEC_free (breakpoint_p, tp_vec);
if (has_pending_p)
warning (_("Pending tracepoints will not be resolved while"
}
void
-start_tracing (char *notes)
+start_tracing (const char *notes)
{
- VEC(breakpoint_p) *tp_vec = NULL;
- int ix;
- struct breakpoint *b;
- struct trace_state_variable *tsv;
int any_enabled = 0, num_to_download = 0;
int ret;
- tp_vec = all_tracepoints ();
+ std::vector<breakpoint *> tp_vec = all_tracepoints ();
/* No point in tracing without any tracepoints... */
- if (VEC_length (breakpoint_p, tp_vec) == 0)
- {
- VEC_free (breakpoint_p, tp_vec);
- error (_("No tracepoints defined, not starting trace"));
- }
+ if (tp_vec.empty ())
+ error (_("No tracepoints defined, not starting trace"));
- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
+ for (breakpoint *b : tp_vec)
{
if (b->enable_state == bp_enabled)
any_enabled = 1;
{
/* No point in tracing with only disabled tracepoints that
cannot be re-enabled. */
- VEC_free (breakpoint_p, tp_vec);
error (_("No tracepoints enabled, not starting trace"));
}
}
if (num_to_download <= 0)
- {
- VEC_free (breakpoint_p, tp_vec);
- error (_("No tracepoints that may be downloaded, not starting trace"));
- }
+ error (_("No tracepoints that may be downloaded, not starting trace"));
target_trace_init ();
- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
+ for (breakpoint *b : tp_vec)
{
struct tracepoint *t = (struct tracepoint *) b;
struct bp_location *loc;
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);
+ gdb::observers::breakpoint_modified.notify (b);
}
- 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 ();
anybody else messing with the target. */
static void
-trace_start_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
-trace_stop_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;
- int ix;
- struct breakpoint *t;
target_trace_stop ();
- tp_vec = all_tracepoints ();
- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
+ for (breakpoint *t : all_tracepoints ())
{
struct bp_location *loc;
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);
}
}
- VEC_free (breakpoint_p, tp_vec);
-
if (!note)
note = trace_stop_notes;
ret = target_set_trace_notes (NULL, NULL, note);
/* tstatus command */
static void
-trace_status_command (char *args, int from_tty)
+tstatus_command (const char *args, int from_tty)
{
struct trace_status *ts = current_trace_status ();
- int status, ix;
- VEC(breakpoint_p) *tp_vec = NULL;
- struct breakpoint *t;
+ int status;
status = target_get_trace_status (ts);
case trace_never_run:
printf_filtered (_("No trace has been run on the target.\n"));
break;
- case tstop_command:
+ case trace_stop_command:
if (ts->stop_desc)
printf_filtered (_("Trace stopped by a tstop command (%s).\n"),
ts->stop_desc);
(long int) (ts->stop_time % 1000000));
/* Now report any per-tracepoint status available. */
- tp_vec = all_tracepoints ();
-
- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
+ for (breakpoint *t : all_tracepoints ())
target_get_tracepoint_status (t, NULL);
-
- VEC_free (breakpoint_p, tp_vec);
}
/* Report the trace status to uiout, in a way suitable for MI, and not
if (status == -1 && ts->filename == NULL)
{
- ui_out_field_string (uiout, "supported", "0");
+ uiout->field_string ("supported", "0");
return;
}
if (ts->filename != NULL)
- ui_out_field_string (uiout, "supported", "file");
+ uiout->field_string ("supported", "file");
else if (!on_stop)
- ui_out_field_string (uiout, "supported", "1");
+ uiout->field_string ("supported", "1");
if (ts->filename != NULL)
- ui_out_field_string (uiout, "trace-file", ts->filename);
+ uiout->field_string ("trace-file", ts->filename);
gdb_assert (ts->running_known);
if (ts->running)
{
- ui_out_field_string (uiout, "running", "1");
+ uiout->field_string ("running", "1");
/* Unlike CLI, do not show the state of 'disconnected-tracing' variable.
Given that the frontend gets the status either on -trace-stop, or from
}
else
{
- char *stop_reason = NULL;
+ const char *stop_reason = NULL;
int stopping_tracepoint = -1;
if (!on_stop)
- ui_out_field_string (uiout, "running", "0");
+ uiout->field_string ("running", "0");
if (ts->stop_reason != trace_stop_reason_unknown)
{
switch (ts->stop_reason)
{
- case tstop_command:
+ case trace_stop_command:
stop_reason = "request";
break;
case trace_buffer_full:
if (stop_reason)
{
- ui_out_field_string (uiout, "stop-reason", stop_reason);
+ uiout->field_string ("stop-reason", stop_reason);
if (stopping_tracepoint != -1)
- ui_out_field_int (uiout, "stopping-tracepoint",
- stopping_tracepoint);
+ uiout->field_signed ("stopping-tracepoint",
+ stopping_tracepoint);
if (ts->stop_reason == tracepoint_error)
- ui_out_field_string (uiout, "error-description",
+ uiout->field_string ("error-description",
ts->stop_desc);
}
}
}
if (ts->traceframe_count != -1)
- ui_out_field_int (uiout, "frames", ts->traceframe_count);
+ uiout->field_signed ("frames", ts->traceframe_count);
if (ts->traceframes_created != -1)
- ui_out_field_int (uiout, "frames-created", ts->traceframes_created);
+ uiout->field_signed ("frames-created", ts->traceframes_created);
if (ts->buffer_size != -1)
- ui_out_field_int (uiout, "buffer-size", ts->buffer_size);
+ uiout->field_signed ("buffer-size", ts->buffer_size);
if (ts->buffer_free != -1)
- ui_out_field_int (uiout, "buffer-free", ts->buffer_free);
+ uiout->field_signed ("buffer-free", ts->buffer_free);
- ui_out_field_int (uiout, "disconnected", ts->disconnected_tracing);
- ui_out_field_int (uiout, "circular", ts->circular_buffer);
+ uiout->field_signed ("disconnected", ts->disconnected_tracing);
+ uiout->field_signed ("circular", ts->circular_buffer);
- ui_out_field_string (uiout, "user-name", ts->user_name);
- ui_out_field_string (uiout, "notes", ts->notes);
+ uiout->field_string ("user-name", ts->user_name);
+ uiout->field_string ("notes", ts->notes);
{
char buf[100];
xsnprintf (buf, sizeof buf, "%ld.%06ld",
(long int) (ts->start_time / 1000000),
(long int) (ts->start_time % 1000000));
- ui_out_field_string (uiout, "start-time", buf);
+ uiout->field_string ("start-time", buf);
xsnprintf (buf, sizeof buf, "%ld.%06ld",
(long int) (ts->stop_time / 1000000),
(long int) (ts->stop_time % 1000000));
- ui_out_field_string (uiout, "stop-time", buf);
+ uiout->field_string ("stop-time", buf);
}
}
DON'T give an error, but DO change the state of
traceframe_number etc. to invalid.
- The rationalle is that if you typed the command, you
+ The rationale is that if you typed the command, you
might just have committed a typo or something, and you'd
like to NOT lose your current debugging state. However
if you're in a user-defined command or especially in a
#if 0 /* dubious now? */
/* The following will not recurse, since it's
special-cased. */
- trace_find_command ("-1", from_tty);
+ tfind_command ("-1", from_tty);
#endif
}
}
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);
+ gdb::observers::traceframe_changed.notify (target_frameno, tracepoint_number);
set_current_traceframe (target_frameno);
{
/* Use different branches for MI and CLI to make CLI messages
i18n-eable. */
- if (ui_out_is_mi_like_p (uiout))
+ if (uiout->is_mi_like_p ())
{
- ui_out_field_string (uiout, "found", "1");
- ui_out_field_int (uiout, "tracepoint", tracepoint_number);
- ui_out_field_int (uiout, "traceframe", traceframe_number);
+ uiout->field_string ("found", "1");
+ uiout->field_signed ("tracepoint", tracepoint_number);
+ uiout->field_signed ("traceframe", traceframe_number);
}
else
{
}
else
{
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "found", "0");
+ if (uiout->is_mi_like_p ())
+ uiout->field_string ("found", "0");
else if (type == tfind_number && num == -1)
printf_unfiltered (_("No longer looking at any trace frame\n"));
else /* This case may never occur, check. */
/* tfind command */
static void
-trace_find_command (char *args, int from_tty)
+tfind_command_1 (const char *args, int from_tty)
{ /* This should only be called with a numeric argument. */
int frameno = -1;
tfind_1 (tfind_number, frameno, 0, 0, from_tty);
}
+static void
+tfind_command (const char *args, int from_tty)
+{
+ tfind_command_1 (args, from_tty);
+}
+
/* tfind end */
static void
-trace_find_end_command (char *args, int from_tty)
+tfind_end_command (const char *args, int from_tty)
{
- trace_find_command ("-1", from_tty);
+ tfind_command_1 ("-1", from_tty);
}
/* tfind start */
static void
-trace_find_start_command (char *args, int from_tty)
+tfind_start_command (const char *args, int from_tty)
{
- trace_find_command ("0", from_tty);
+ tfind_command_1 ("0", from_tty);
}
/* tfind pc command */
static void
-trace_find_pc_command (char *args, int from_tty)
+tfind_pc_command (const char *args, int from_tty)
{
CORE_ADDR pc;
/* tfind tracepoint command */
static void
-trace_find_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
-trace_find_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
-trace_find_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 (args == 0 || *args == 0)
{ /* XXX FIXME: what should default behavior be? */
- printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
+ printf_filtered ("Usage: tfind range STARTADDR, ENDADDR\n");
return;
}
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
-trace_find_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 (args == 0 || *args == 0)
{ /* XXX FIXME: what should default behavior be? */
- printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
+ printf_filtered ("Usage: tfind outside STARTADDR, ENDADDR\n");
return;
}
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;
- struct event_location *location;
- struct cleanup *back_to;
+ const char *args = args_in;
if (args == 0 || *args == 0)
error (_("requires an argument (function, "
"line or *addr) to define a scope"));
- location = string_to_event_location (&args, current_language);
- back_to = make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE, NULL, NULL, 0);
- if (sals.nelts == 0)
+ event_location_up location = string_to_event_location (&args,
+ current_language);
+ 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. */
- do_cleanups (back_to);
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)
{
printf_filtered ("Scope for %s:\n", save_args);
count++;
- symname = SYMBOL_PRINT_NAME (sym);
+ symname = sym->print_name ();
if (symname == NULL || *symname == '\0')
continue; /* Probably botched, certainly useless. */
if (SYMBOL_COMPUTED_OPS (sym) != NULL)
SYMBOL_COMPUTED_OPS (sym)->describe_location (sym,
- BLOCK_START (block),
+ BLOCK_ENTRY_PC (block),
gdb_stdout);
else
{
case LOC_BLOCK:
printf_filtered ("a function at address ");
printf_filtered ("%s",
- paddress (gdbarch, BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
+ paddress (gdbarch, BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym))));
break;
case LOC_UNRESOLVED:
- msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (sym),
+ msym = lookup_minimal_symbol (sym->linkage_name (),
NULL, NULL);
if (msym.minsym == NULL)
printf_filtered ("Unresolved Static");
}
}
if (SYMBOL_TYPE (sym))
- printf_filtered (", length %d.\n",
- TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
+ {
+ struct type *t = check_typedef (SYMBOL_TYPE (sym));
+
+ printf_filtered (", length %s.\n", pulongest (TYPE_LENGTH (t)));
+ }
}
if (BLOCK_FUNCTION (block))
break;
if (count <= 0)
printf_filtered ("Scope for %s contains no locals or arguments.\n",
save_args);
- do_cleanups (back_to);
}
/* Helper for trace_dump_command. Dump the action list starting at
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". */
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))
{
STEPPING_ACTIONS should be equal. */
if (stepping_frame == stepping_actions)
{
- char *cmd = NULL;
- struct cleanup *old_chain
- = make_cleanup (free_current_contents, &cmd);
int trace_string = 0;
if (*action_exp == '/')
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 */
+ std::string contents;
+ const char *exp = action_exp;
if (next_comma != NULL)
{
size_t len = next_comma - action_exp;
-
- cmd = (char *) xrealloc (cmd, len + 1);
- memcpy (cmd, action_exp, len);
- cmd[len] = 0;
- }
- else
- {
- size_t len = strlen (action_exp);
-
- cmd = (char *) xrealloc (cmd, len + 1);
- memcpy (cmd, action_exp, len + 1);
+ contents = std::string (action_exp, len);
+ exp = contents.c_str ();
}
- printf_filtered ("%s = ", cmd);
- output_command_const (cmd, from_tty);
+ printf_filtered ("%s = ", exp);
+ output_command (exp, from_tty);
printf_filtered ("\n");
}
action_exp = next_comma;
}
while (action_exp && *action_exp == ',');
-
- do_cleanups (old_chain);
}
}
}
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
- 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
the fly, and don't cache it. */
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);
-
- 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;
+ gdb::unique_xmalloc_ptr<char> default_collect_line
+ (xstrprintf ("collect %s", default_collect));
+
+ validate_actionline (default_collect_line.get (), t);
+ actions.reset (new struct command_line (simple_control,
+ default_collect_line.release ()),
+ command_lines_deleter ());
}
return actions;
/* The tdump command. */
static void
-trace_dump_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. */
loc = 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 ());
+ scoped_restore_current_thread restore_thread;
- actions = all_tracepoint_actions_and_cleanup (loc->owner);
+ select_frame (get_current_frame ());
- trace_dump_actions (actions, 0, stepping_frame, from_tty);
+ counted_command_line actions = all_tracepoint_actions (loc->owner);
- do_cleanups (old_chain);
+ 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
/* This version does not do multiple encodes for long strings; it should
return an offset to the next piece to encode. FIXME */
-extern int
+int
encode_source_string (int tpnum, ULONGEST addr,
- char *srctype, const char *src, char *buf, int buf_size)
+ const char *srctype, const char *src,
+ char *buf, int buf_size)
{
if (80 + strlen (srctype) > buf_size)
error (_("Buffer too small for source encoding"));
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;
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;
}
}
static struct bp_location *
find_matching_tracepoint_location (struct uploaded_tp *utp)
{
- VEC(breakpoint_p) *tp_vec = all_tracepoints ();
- int ix;
- struct breakpoint *b;
struct bp_location *loc;
- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
+ for (breakpoint *b : all_tracepoints ())
{
struct tracepoint *t = (struct tracepoint *) b;
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.get ())
/* FIXME also test actions. */
)
{
{
struct uploaded_tp *utp;
/* A set of tracepoints which are modified. */
- VEC(breakpoint_p) *modified_tp = NULL;
- int ix;
- struct breakpoint *b;
+ std::vector<breakpoint *> modified_tp;
/* Look for GDB tracepoints that match up with our uploaded versions. */
for (utp = *uploaded_tps; utp; utp = utp->next)
MODIFIED_TP if not there yet. The 'breakpoint-modified'
observers will be notified later once for each tracepoint
saved in MODIFIED_TP. */
- for (ix = 0;
- VEC_iterate (breakpoint_p, modified_tp, ix, b);
- ix++)
+ for (breakpoint *b : modified_tp)
if (b == loc->owner)
{
found = 1;
break;
}
if (!found)
- VEC_safe_push (breakpoint_p, modified_tp, loc->owner);
+ modified_tp.push_back (loc->owner);
}
else
{
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 "
/* Notify 'breakpoint-modified' observer that at least one of B's
locations was changed. */
- for (ix = 0; VEC_iterate (breakpoint_p, modified_tp, ix, b); ix++)
- observer_notify_breakpoint_modified (b);
+ for (breakpoint *b : modified_tp)
+ gdb::observers::breakpoint_modified.notify (b);
- VEC_free (breakpoint_p, modified_tp);
free_uploaded_tps (uploaded_tps);
}
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);
+ gdb::observers::tsv_created.notify (tsv);
return tsv;
}
void
merge_uploaded_trace_state_variables (struct uploaded_tsv **uploaded_tsvs)
{
- int ix;
struct uploaded_tsv *utsv;
- struct trace_state_variable *tsv;
int highest;
/* 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)
{
- tsv = find_matching_tsv (utsv);
+ struct trace_state_variable *tsv = find_matching_tsv (utsv);
if (tsv)
{
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);
}
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;
ts->stop_reason = tracepoint_passcount;
ts->stopping_tracepoint = val;
}
- else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
+ else if (strncmp (p, stop_reason_names[trace_stop_command], p1 - p) == 0)
{
p2 = strchr (++p1, ':');
if (!p2 || p2 > p3)
ts->stop_desc = xstrdup ("");
p = unpack_varlen_hex (++p2, &val);
- ts->stop_reason = tstop_command;
+ ts->stop_reason = trace_stop_command;
}
else if (strncmp (p, stop_reason_names[trace_disconnected], p1 - p) == 0)
{
}
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 *buf;
struct uploaded_tp *utp = NULL;
p = line;
p++; /* skip a colon */
if (piece == 'T')
{
+ gdb::unique_xmalloc_ptr<char[]> cond;
+
enabled = (*p++ == 'E');
p++; /* skip a colon */
p = unpack_varlen_hex (p, &step);
p++; /* skip a colon */
p = unpack_varlen_hex (p, &pass);
type = bp_tracepoint;
- cond = NULL;
/* Thumb through optional fields. */
while (*p == ':')
{
p++;
p = unpack_varlen_hex (p, &xlen);
p++; /* skip a comma */
- cond = (char *) xmalloc (2 * xlen + 1);
- strncpy (cond, p, 2 * xlen);
+ cond.reset ((char *) xmalloc (2 * xlen + 1));
+ strncpy (&cond[0], p, 2 * xlen);
cond[2 * xlen] = '\0';
p += 2 * xlen;
}
utp->enabled = enabled;
utp->step = step;
utp->pass = pass;
- utp->cond = cond;
+ utp->cond = std::move (cond);
}
else if (piece == 'A')
{
utp = get_uploaded_tp (num, addr, utpp);
- VEC_safe_push (char_ptr, utp->actions, xstrdup (p));
+ utp->actions.emplace_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.emplace_back (xstrdup (p));
}
else if (piece == 'Z')
{
buf[end] = '\0';
if (startswith (srctype, "at:"))
- utp->at_string = xstrdup (buf);
+ utp->at_string.reset (xstrdup (buf));
else if (startswith (srctype, "cond:"))
- utp->cond_string = xstrdup (buf);
+ utp->cond_string.reset (xstrdup (buf));
else if (startswith (srctype, "cmd:"))
- VEC_safe_push (char_ptr, utp->cmd_strings, xstrdup (buf));
+ utp->cmd_strings.emplace_back (xstrdup (buf));
}
else if (piece == 'V')
{
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;
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
the parsed marker definition. */
void
-parse_static_tracepoint_marker_definition (char *line, char **pp,
- struct static_tracepoint_marker *marker)
+parse_static_tracepoint_marker_definition (const char *line, const char **pp,
+ static_tracepoint_marker *marker)
{
- char *p, *endp;
+ 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';
+ marker->str_id = hex2str (p, (endp - p) / 2);
- p += 2 * end;
- p++; /* skip a colon */
-
- 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;
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;
- sal.pc = marker->address;
+ std::vector<breakpoint *> tracepoints
+ = static_tracepoints_here (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! */
- ui_out_field_int (uiout, "count", count);
+ uiout->field_signed ("count", count);
- ui_out_field_string (uiout, "marker-id", marker->str_id);
+ uiout->field_string ("marker-id", marker.str_id.c_str ());
- ui_out_field_fmt (uiout, "enabled", "%c",
- !VEC_empty (breakpoint_p, tracepoints) ? 'y' : 'n');
- ui_out_spaces (uiout, 2);
+ uiout->field_fmt ("enabled", "%c",
+ !tracepoints.empty () ? 'y' : 'n');
+ uiout->spaces (2);
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, " ");
- ui_out_field_core_addr (uiout, "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)
{
- ui_out_text (uiout, "in ");
- ui_out_field_string (uiout, "func",
- SYMBOL_PRINT_NAME (sym));
- ui_out_wrap_hint (uiout, wrap_indent);
- ui_out_text (uiout, " at ");
+ uiout->text ("in ");
+ uiout->field_string ("func", sym->print_name (),
+ function_name_style.style ());
+ uiout->wrap_hint (wrap_indent);
+ uiout->text (" at ");
}
else
- ui_out_field_skip (uiout, "func");
+ uiout->field_skip ("func");
if (sal.symtab != NULL)
{
- ui_out_field_string (uiout, "file",
- symtab_to_filename_for_display (sal.symtab));
- ui_out_text (uiout, ":");
+ uiout->field_string ("file",
+ symtab_to_filename_for_display (sal.symtab),
+ file_name_style.style ());
+ uiout->text (":");
- if (ui_out_is_mi_like_p (uiout))
+ if (uiout->is_mi_like_p ())
{
const char *fullname = symtab_to_fullname (sal.symtab);
- ui_out_field_string (uiout, "fullname", fullname);
+ uiout->field_string ("fullname", fullname);
}
else
- ui_out_field_skip (uiout, "fullname");
+ uiout->field_skip ("fullname");
- ui_out_field_int (uiout, "line", sal.line);
+ uiout->field_signed ("line", sal.line);
}
else
{
- ui_out_field_skip (uiout, "fullname");
- ui_out_field_skip (uiout, "line");
+ uiout->field_skip ("fullname");
+ uiout->field_skip ("line");
}
- ui_out_text (uiout, "\n");
- ui_out_text (uiout, extra_field_indent);
- ui_out_text (uiout, _("Data: \""));
- ui_out_field_string (uiout, "extra-data", marker->extra);
- ui_out_text (uiout, "\"\n");
+ uiout->text ("\n");
+ uiout->text (extra_field_indent);
+ uiout->text (_("Data: \""));
+ uiout->field_string ("extra-data", marker.extra.c_str ());
+ uiout->text ("\"\n");
- if (!VEC_empty (breakpoint_p, tracepoints))
+ if (!tracepoints.empty ())
{
- struct cleanup *cleanup_chain;
int ix;
- struct breakpoint *b;
- cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
- "tracepoints-at");
-
- ui_out_text (uiout, extra_field_indent);
- ui_out_text (uiout, _("Probed by static tracepoints: "));
- for (ix = 0; VEC_iterate(breakpoint_p, tracepoints, ix, b); ix++)
- {
- if (ix > 0)
- ui_out_text (uiout, ", ");
- ui_out_text (uiout, "#");
- ui_out_field_int (uiout, "tracepoint-id", b->number);
- }
+ {
+ ui_out_emit_tuple inner_tuple_emitter (uiout, "tracepoints-at");
- do_cleanups (cleanup_chain);
+ uiout->text (extra_field_indent);
+ uiout->text (_("Probed by static tracepoints: "));
+ for (ix = 0; ix < tracepoints.size (); ix++)
+ {
+ if (ix > 0)
+ uiout->text (", ");
+ uiout->text ("#");
+ uiout->field_signed ("tracepoint-id", tracepoints[ix]->number);
+ }
+ }
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_int (uiout, "number-of-tracepoints",
- VEC_length(breakpoint_p, tracepoints));
+ if (uiout->is_mi_like_p ())
+ uiout->field_signed ("number-of-tracepoints", tracepoints.size ());
else
- ui_out_text (uiout, "\n");
+ 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;
- 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.
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");
- ui_out_table_header (uiout, 7, ui_left, "counter", "Cnt");
+ uiout->table_header (7, ui_left, "counter", "Cnt");
- ui_out_table_header (uiout, 40, ui_left, "marker-id", "ID");
+ uiout->table_header (40, ui_left, "marker-id", "ID");
- ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");
+ uiout->table_header (3, ui_left, "enabled", "Enb");
if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
- ui_out_table_header (uiout, 10, ui_left, "addr", "Address");
+ uiout->table_header (10, ui_left, "addr", "Address");
else
- ui_out_table_header (uiout, 18, ui_left, "addr", "Address");
- ui_out_table_header (uiout, 40, ui_noalign, "what", "What");
-
- ui_out_table_body (uiout);
+ uiout->table_header (18, ui_left, "addr", "Address");
+ uiout->table_header (40, ui_noalign, "what", "What");
- markers = target_static_tracepoint_markers_by_strid (NULL);
- 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);
- }
+ uiout->table_body ();
- 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 (current_top_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
#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);
+ tframe_info, result.get ()) == 0)
+ return result;
- 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;
}
NULL
};
+/* See tracepoint.h. */
+cmd_list_element *while_stepping_cmd_element = nullptr;
+
/* module initialization */
void
_initialize_tracepoint (void)
traceframe_number = -1;
tracepoint_number = -1;
- add_info ("scope", scope_info,
- _("List the variables local to a scope"));
+ 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);
- add_com ("tdump", class_trace, trace_dump_command,
+ add_com ("tdump", class_trace, tdump_command,
_("Print everything collected at the current tracepoint."));
c = add_com ("tvariable", class_trace, trace_variable_command,_("\
If no arguments are supplied, delete all variables."), &deletelist);
/* FIXME add a trace variable completer. */
- add_info ("tvariables", tvariables_info, _("\
-Status of trace state variables and their values.\n\
-"));
+ add_info ("tvariables", info_tvariables_command, _("\
+Status of trace state variables and their values."));
add_info ("static-tracepoint-markers",
info_static_tracepoint_markers_command, _("\
-List target static tracepoints markers.\n\
-"));
+List target static tracepoints markers."));
- add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
-Select a trace frame;\n\
+ add_prefix_cmd ("tfind", class_trace, tfind_command, _("\
+Select a trace frame.\n\
No argument means forward by one frame; '-' means backward by one frame."),
&tfindlist, "tfind ", 1, &cmdlist);
- add_cmd ("outside", class_trace, trace_find_outside_command, _("\
+ add_cmd ("outside", class_trace, tfind_outside_command, _("\
Select a trace frame whose PC is outside the given range (exclusive).\n\
-Usage: tfind outside addr1, addr2"),
+Usage: tfind outside ADDR1, ADDR2"),
&tfindlist);
- add_cmd ("range", class_trace, trace_find_range_command, _("\
+ add_cmd ("range", class_trace, tfind_range_command, _("\
Select a trace frame whose PC is in the given range (inclusive).\n\
-Usage: tfind range addr1,addr2"),
+Usage: tfind range ADDR1, ADDR2"),
&tfindlist);
- add_cmd ("line", class_trace, trace_find_line_command, _("\
+ add_cmd ("line", class_trace, tfind_line_command, _("\
Select a trace frame by source line.\n\
Argument can be a line number (with optional source file),\n\
a function name, or '*' followed by an address.\n\
Default argument is 'the next source line that was traced'."),
&tfindlist);
- add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command, _("\
+ add_cmd ("tracepoint", class_trace, tfind_tracepoint_command, _("\
Select a trace frame by tracepoint number.\n\
Default is the tracepoint for the current trace frame."),
&tfindlist);
- add_cmd ("pc", class_trace, trace_find_pc_command, _("\
+ add_cmd ("pc", class_trace, tfind_pc_command, _("\
Select a trace frame by PC.\n\
Default is the current PC, or the PC of the current trace frame."),
&tfindlist);
- add_cmd ("end", class_trace, trace_find_end_command, _("\
+ add_cmd ("end", class_trace, tfind_end_command, _("\
De-select any trace frame and resume 'live' debugging."),
&tfindlist);
add_alias_cmd ("none", "end", class_trace, 0, &tfindlist);
- add_cmd ("start", class_trace, trace_find_start_command,
+ add_cmd ("start", class_trace, tfind_start_command,
_("Select the first trace frame in the trace buffer."),
&tfindlist);
- add_com ("tstatus", class_trace, trace_status_command,
+ add_com ("tstatus", class_trace, tstatus_command,
_("Display the status of the current trace data collection."));
- add_com ("tstop", class_trace, trace_stop_command, _("\
+ add_com ("tstop", class_trace, tstop_command, _("\
Stop trace data collection.\n\
-Usage: tstop [ <notes> ... ]\n\
+Usage: tstop [NOTES]...\n\
Any arguments supplied are recorded with the trace as a stop reason and\n\
reported by tstatus (if the target supports trace notes)."));
- add_com ("tstart", class_trace, trace_start_command, _("\
+ add_com ("tstart", class_trace, tstart_command, _("\
Start trace data collection.\n\
-Usage: tstart [ <notes> ... ]\n\
+Usage: tstart [NOTES]...\n\
Any arguments supplied are recorded with the trace as a note and\n\
reported by tstatus (if the target supports trace notes)."));
such a list.\n\n\
Note: the \"end\" command cannot be used at the gdb prompt."));
- add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
+ while_stepping_cmd_element = add_com ("while-stepping", class_trace,
+ while_stepping_pseudocommand, _("\
Specify single-stepping behavior at a tracepoint.\n\
Argument is number of instructions to trace in single-step mode\n\
following the tracepoint. This command is normally followed by\n\
The result of each evaluation will be discarded.\n\
Note: this command can only be used in a tracepoint \"actions\" list."));
- add_com ("actions", class_trace, trace_actions_command, _("\
+ add_com ("actions", class_trace, actions_command, _("\
Specify the actions to be taken at a tracepoint.\n\
Tracepoint actions may include collecting of specified data,\n\
single-stepping, or enabling/disabling other tracepoints,\n\
default_collect = xstrdup ("");
add_setshow_string_cmd ("default-collect", class_trace,
&default_collect, _("\
-Set the list of expressions to collect by default"), _("\
-Show the list of expressions to collect by default"), NULL,
+Set the list of expressions to collect by default."), _("\
+Show the list of expressions to collect by default."), NULL,
NULL, NULL,
&setlist, &showlist);
add_setshow_string_cmd ("trace-user", class_trace,
&trace_user, _("\
-Set the user name to use for current and future trace runs"), _("\
-Show the user name to use for current and future trace runs"), NULL,
+Set the user name to use for current and future trace runs."), _("\
+Show the user name to use for current and future trace runs."), NULL,
set_trace_user, NULL,
&setlist, &showlist);
add_setshow_string_cmd ("trace-notes", class_trace,
&trace_notes, _("\
-Set notes string to use for current and future trace runs"), _("\
-Show the notes string to use for current and future trace runs"), NULL,
+Set notes string to use for current and future trace runs."), _("\
+Show the notes string to use for current and future trace runs."), NULL,
set_trace_notes, NULL,
&setlist, &showlist);
add_setshow_string_cmd ("trace-stop-notes", class_trace,
&trace_stop_notes, _("\
-Set notes string to use for future tstop commands"), _("\
-Show the notes string to use for future tstop commands"), NULL,
+Set notes string to use for future tstop commands."), _("\
+Show the notes string to use for future tstop commands."), NULL,
set_trace_stop_notes, NULL,
&setlist, &showlist);
}