X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftracepoint.c;h=8e04cad504e9a039c51204bfe9021ef818d7967a;hb=351259211aa638e02e2962223c87e4aced1010e4;hp=d99d663895fbbf1a51f6132baad0c844fcd7c925;hpb=02d016b71fd38648fad589c1557b83135b1dd552;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index d99d663895..8e04cad504 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -1,6 +1,6 @@ /* Tracing functionality for remote targets in custom GDB protocol - Copyright (C) 1997-2018 Free Software Foundation, Inc. + Copyright (C) 1997-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -51,19 +51,12 @@ #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 - -/* readline include files */ -#include "readline/readline.h" -#include "readline/history.h" - -/* readline defines this. */ -#undef savestring +#include "cli/cli-style.h" #include @@ -138,12 +131,12 @@ static struct cmd_list_element *tfindlist; /* List of expressions to collect by default at each tracepoint hit. */ 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. */ @@ -243,11 +236,11 @@ set_traceframe_context (struct frame_info *trace_frame) /* 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. */ @@ -442,6 +435,7 @@ tvariables_info_1 (void) 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 ()) @@ -450,13 +444,19 @@ tvariables_info_1 (void) 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 = ""; + { + /* The value is/was defined, but we don't have it. */ + c = ""; + style = metadata_style.style (); + } else - /* It is not meaningful to ask about the value. */ - c = ""; + { + /* It is not meaningful to ask about the value. */ + c = ""; + style = metadata_style.style (); + } if (c) - uiout->field_string ("current", c); + uiout->field_string ("current", c, style); uiout->text ("\n"); } } @@ -615,6 +615,19 @@ report_agent_reqs_errors (struct agent_expr *aexpr) 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) @@ -680,7 +693,7 @@ validate_actionline (const char *line, struct breakpoint *b) { 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) @@ -688,7 +701,7 @@ validate_actionline (const char *line, struct breakpoint *b) { error (_("`%s' is optimized away " "and cannot be collected."), - SYMBOL_PRINT_NAME (exp->elts[2].symbol)); + exp->elts[2].symbol->print_name ()); } } @@ -699,12 +712,7 @@ validate_actionline (const char *line, struct breakpoint *b) exp.get (), trace_string); - if (aexpr->len > MAX_AGENT_EXPR_LEN) - error (_("Expression is too complicated.")); - - ax_reqs (aexpr.get ()); - - report_agent_reqs_errors (aexpr.get ()); + finalize_tracepoint_aexpr (aexpr.get ()); } } while (p && *p++ == ','); @@ -731,11 +739,7 @@ validate_actionline (const char *line, struct breakpoint *b) long. */ agent_expr_up aexpr = gen_eval_for_expr (loc->address, exp.get ()); - if (aexpr->len > MAX_AGENT_EXPR_LEN) - error (_("Expression is too complicated.")); - - ax_reqs (aexpr.get ()); - report_agent_reqs_errors (aexpr.get ()); + finalize_tracepoint_aexpr (aexpr.get ()); } } while (p && *p++ == ','); @@ -811,17 +815,77 @@ memrange_sortmerge (std::vector &memranges) } } -/* 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 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_ax_registers (struct agent_expr *aexpr) +{ + if (aexpr->reg_mask_len > 0) + { + 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. */ @@ -829,7 +893,7 @@ collection_list::add_register (unsigned int regno) void collection_list::add_memrange (struct gdbarch *gdbarch, int type, bfd_signed_vma base, - unsigned long len) + unsigned long len, CORE_ADDR scope) { if (info_verbose) printf_filtered ("(%d,%s,%ld)\n", type, paddress (gdbarch, base), len); @@ -840,7 +904,7 @@ collection_list::add_memrange (struct gdbarch *gdbarch, 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. */ @@ -862,19 +926,18 @@ collection_list::collect_symbol (struct symbol *sym, { 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) { printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n", - SYMBOL_PRINT_NAME (sym), len, + sym->print_name (), len, paddress (gdbarch, offset)); } /* A struct may be a C++ class with static fields, go to general @@ -882,24 +945,22 @@ collection_list::collect_symbol (struct symbol *sym, if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT) treat_as_expr = 1; else - add_memrange (gdbarch, 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; @@ -907,11 +968,10 @@ collection_list::collect_symbol (struct symbol *sym, if (info_verbose) { printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset %s" - " from frame ptr reg %d\n", - SYMBOL_PRINT_NAME (sym), len, + " from frame ptr reg %d\n", sym->print_name (), len, paddress (gdbarch, offset), reg); } - add_memrange (gdbarch, reg, offset, len); + add_memrange (gdbarch, reg, offset, len, scope); break; case LOC_REGPARM_ADDR: reg = SYMBOL_VALUE (sym); @@ -919,11 +979,10 @@ collection_list::collect_symbol (struct symbol *sym, if (info_verbose) { printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset %s" - " from reg %d\n", - SYMBOL_PRINT_NAME (sym), len, + " from reg %d\n", sym->print_name (), len, paddress (gdbarch, offset), reg); } - add_memrange (gdbarch, reg, offset, len); + add_memrange (gdbarch, reg, offset, len, scope); break; case LOC_LOCAL: reg = frame_regno; @@ -931,11 +990,10 @@ collection_list::collect_symbol (struct symbol *sym, if (info_verbose) { printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset %s" - " from frame ptr reg %d\n", - SYMBOL_PRINT_NAME (sym), len, + " from frame ptr reg %d\n", sym->print_name (), len, paddress (gdbarch, offset), reg); } - add_memrange (gdbarch, reg, offset, len); + add_memrange (gdbarch, reg, offset, len, scope); break; case LOC_UNRESOLVED: @@ -944,7 +1002,7 @@ collection_list::collect_symbol (struct symbol *sym, 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: @@ -964,30 +1022,14 @@ collection_list::collect_symbol (struct symbol *sym, if (!aexpr) { printf_filtered ("%s has been optimized out of existence.\n", - SYMBOL_PRINT_NAME (sym)); + sym->print_name ()); return; } - ax_reqs (aexpr.get ()); - - report_agent_reqs_errors (aexpr.get ()); + finalize_tracepoint_aexpr (aexpr.get ()); /* Take care of the registers. */ - if (aexpr->reg_mask_len > 0) - { - 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_register (ndx1 * 8 + ndx2); - } - } - } + add_ax_registers (aexpr.get ()); add_aexpr (std::move (aexpr)); } @@ -1086,9 +1128,20 @@ collection_list::add_static_trace_data () } 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); } @@ -1098,7 +1151,8 @@ collection_list::collection_list () std::vector collection_list::stringify () { - char temp_buf[2048]; + gdb::char_vector temp_buf (2048); + int count; char *end; long i; @@ -1108,35 +1162,45 @@ collection_list::stringify () { if (info_verbose) printf_filtered ("\nCollecting static trace data\n"); - end = temp_buf; + end = temp_buf.data (); *end++ = 'L'; - str_list.emplace_back (temp_buf, end - temp_buf); + 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.emplace_back (temp_buf); + *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. */ if (info_verbose) @@ -1150,9 +1214,9 @@ collection_list::stringify () } if (count + 27 > MAX_AGENT_EXPR_LEN) { - str_list.emplace_back (temp_buf, count); + str_list.emplace_back (temp_buf.data (), count); count = 0; - end = temp_buf; + end = temp_buf.data (); } { @@ -1172,7 +1236,7 @@ collection_list::stringify () } count += strlen (end); - end = temp_buf + count; + end = temp_buf.data () + count; } for (i = 0; i < m_aexprs.size (); i++) @@ -1180,9 +1244,9 @@ collection_list::stringify () QUIT; /* Allow user to bail out with ^C. */ if ((count + 10 + 2 * m_aexprs[i]->len) > MAX_AGENT_EXPR_LEN) { - str_list.emplace_back (temp_buf, count); + 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 + ',' */ @@ -1194,9 +1258,9 @@ collection_list::stringify () if (count != 0) { - str_list.emplace_back (temp_buf, count); + str_list.emplace_back (temp_buf.data (), count); count = 0; - end = temp_buf; + end = temp_buf.data (); } return str_list; @@ -1257,8 +1321,18 @@ encode_actions_1 (struct command_line *action, 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)) @@ -1288,27 +1362,10 @@ encode_actions_1 (struct command_line *action, target_gdbarch (), trace_string); - ax_reqs (aexpr.get ()); - report_agent_reqs_errors (aexpr.get ()); + finalize_tracepoint_aexpr (aexpr.get ()); /* take care of the registers */ - if (aexpr->reg_mask_len > 0) - { - 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. */ - collect->add_register (ndx1 * 8 + ndx2); - } - } - } - } + collect->add_ax_registers (aexpr.get ()); collect->add_aexpr (std::move (aexpr)); action_exp = strchr (action_exp, ','); /* more? */ @@ -1340,7 +1397,8 @@ encode_actions_1 (struct command_line *action, name); if (info_verbose) printf_filtered ("OP_REGISTER: "); - collect->add_register (i); + collect->add_local_register (target_gdbarch (), + i, tloc->address); break; } @@ -1352,14 +1410,15 @@ encode_actions_1 (struct command_line *action, check_typedef (exp->elts[1].type); collect->add_memrange (target_gdbarch (), memrange_absolute, addr, - TYPE_LENGTH (exp->elts[1].type)); + 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; - const char *name = SYMBOL_NATURAL_NAME (sym); + const char *name = sym->natural_name (); collect->collect_symbol (exp->elts[2].symbol, target_gdbarch (), @@ -1376,28 +1435,10 @@ encode_actions_1 (struct command_line *action, exp.get (), trace_string); - ax_reqs (aexpr.get ()); - - report_agent_reqs_errors (aexpr.get ()); + finalize_tracepoint_aexpr (aexpr.get ()); /* Take care of the registers. */ - if (aexpr->reg_mask_len > 0) - { - 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. */ - collect->add_register (ndx1 * 8 + ndx2); - } - } - } - } + collect->add_ax_registers (aexpr.get ()); collect->add_aexpr (std::move (aexpr)); collect->append_exp (exp.get ()); @@ -1422,8 +1463,7 @@ encode_actions_1 (struct command_line *action, agent_expr_up aexpr = gen_eval_for_expr (tloc->address, exp.get ()); - ax_reqs (aexpr.get ()); - report_agent_reqs_errors (aexpr.get ()); + finalize_tracepoint_aexpr (aexpr.get ()); /* Even though we're not officially collecting, add to the collect list anyway. */ @@ -1495,15 +1535,11 @@ collection_list::add_aexpr (agent_expr_up 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) { @@ -1527,7 +1563,6 @@ process_tracepoint_on_disconnect (void) break; } } - VEC_free (breakpoint_p, tp_vec); if (has_pending_p) warning (_("Pending tracepoints will not be resolved while" @@ -1548,23 +1583,16 @@ trace_reset_local_state (void) void 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 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; @@ -1586,20 +1614,16 @@ start_tracing (const char *notes) { /* 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; @@ -1638,7 +1662,6 @@ start_tracing (const char *notes) if (bp_location_downloaded) gdb::observers::breakpoint_modified.notify (b); } - VEC_free (breakpoint_p, tp_vec); /* Send down all the trace state variables too. */ for (const trace_state_variable &tsv : tvariables) @@ -1705,14 +1728,10 @@ void 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; @@ -1733,8 +1752,6 @@ stop_tracing (const char *note) } } - VEC_free (breakpoint_p, tp_vec); - if (!note) note = trace_stop_notes; ret = target_set_trace_notes (NULL, NULL, note); @@ -1751,9 +1768,7 @@ static void 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); @@ -1896,12 +1911,8 @@ tstatus_command (const char *args, int from_tty) (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 @@ -1983,8 +1994,8 @@ trace_status_mi (int on_stop) { uiout->field_string ("stop-reason", stop_reason); if (stopping_tracepoint != -1) - uiout->field_int ("stopping-tracepoint", - stopping_tracepoint); + uiout->field_signed ("stopping-tracepoint", + stopping_tracepoint); if (ts->stop_reason == tracepoint_error) uiout->field_string ("error-description", ts->stop_desc); @@ -1993,16 +2004,16 @@ trace_status_mi (int on_stop) } if (ts->traceframe_count != -1) - uiout->field_int ("frames", ts->traceframe_count); + uiout->field_signed ("frames", ts->traceframe_count); if (ts->traceframes_created != -1) - uiout->field_int ("frames-created", ts->traceframes_created); + uiout->field_signed ("frames-created", ts->traceframes_created); if (ts->buffer_size != -1) - uiout->field_int ("buffer-size", ts->buffer_size); + uiout->field_signed ("buffer-size", ts->buffer_size); if (ts->buffer_free != -1) - uiout->field_int ("buffer-free", ts->buffer_free); + uiout->field_signed ("buffer-free", ts->buffer_free); - uiout->field_int ("disconnected", ts->disconnected_tracing); - uiout->field_int ("circular", ts->circular_buffer); + uiout->field_signed ("disconnected", ts->disconnected_tracing); + uiout->field_signed ("circular", ts->circular_buffer); uiout->field_string ("user-name", ts->user_name); uiout->field_string ("notes", ts->notes); @@ -2119,7 +2130,7 @@ tfind_1 (enum trace_find_type type, int num, 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 @@ -2166,8 +2177,8 @@ tfind_1 (enum trace_find_type type, int num, if (uiout->is_mi_like_p ()) { uiout->field_string ("found", "1"); - uiout->field_int ("tracepoint", tracepoint_number); - uiout->field_int ("traceframe", traceframe_number); + uiout->field_signed ("tracepoint", tracepoint_number); + uiout->field_signed ("traceframe", traceframe_number); } else { @@ -2410,7 +2421,7 @@ tfind_range_command (const char *args, int from_tty) if (args == 0 || *args == 0) { /* XXX FIXME: what should default behavior be? */ - printf_filtered ("Usage: tfind range ,\n"); + printf_filtered ("Usage: tfind range STARTADDR, ENDADDR\n"); return; } @@ -2444,7 +2455,7 @@ tfind_outside_command (const char *args, int from_tty) if (args == 0 || *args == 0) { /* XXX FIXME: what should default behavior be? */ - printf_filtered ("Usage: tfind outside ,\n"); + printf_filtered ("Usage: tfind outside STARTADDR, ENDADDR\n"); return; } @@ -2509,7 +2520,7 @@ info_scope_command (const char *args_in, int from_tty) 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. */ @@ -2519,7 +2530,7 @@ info_scope_command (const char *args_in, int from_tty) if (SYMBOL_COMPUTED_OPS (sym) != NULL) SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, - BLOCK_START (block), + BLOCK_ENTRY_PC (block), gdb_stdout); else { @@ -2596,10 +2607,10 @@ info_scope_command (const char *args_in, int from_tty) 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"); @@ -2619,8 +2630,11 @@ info_scope_command (const char *args_in, int from_tty) } } 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; @@ -2780,7 +2794,6 @@ all_tracepoint_actions (struct breakpoint *t) the fly, and don't cache it. */ if (*default_collect) { - struct command_line *default_collect_action; gdb::unique_xmalloc_ptr default_collect_line (xstrprintf ("collect %s", default_collect)); @@ -3058,19 +3071,17 @@ cond_string_is_same (char *str1, char *str2) 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->cond_string, utp->cond_string) + && cond_string_is_same (t->cond_string, + utp->cond_string.get ()) /* FIXME also test actions. */ ) { @@ -3094,9 +3105,7 @@ merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps) { struct uploaded_tp *utp; /* A set of tracepoints which are modified. */ - VEC(breakpoint_p) *modified_tp = NULL; - int ix; - struct breakpoint *b; + std::vector modified_tp; /* Look for GDB tracepoints that match up with our uploaded versions. */ for (utp = *uploaded_tps; utp; utp = utp->next) @@ -3122,16 +3131,14 @@ merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps) 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 { @@ -3156,10 +3163,9 @@ merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps) /* 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++) + for (breakpoint *b : modified_tp) gdb::observers::breakpoint_modified.notify (b); - VEC_free (breakpoint_p, modified_tp); free_uploaded_tps (uploaded_tps); } @@ -3215,9 +3221,7 @@ create_tsv_from_upload (struct uploaded_tsv *utsv) 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 @@ -3227,7 +3231,7 @@ merge_uploaded_trace_state_variables (struct uploaded_tsv **uploaded_tsvs) 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) @@ -3456,7 +3460,7 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp) int enabled, end; enum bptype type; const char *srctype; - char *cond, *buf; + char *buf; struct uploaded_tp *utp = NULL; p = line; @@ -3469,13 +3473,14 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp) p++; /* skip a colon */ if (piece == 'T') { + gdb::unique_xmalloc_ptr 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 == ':') { @@ -3496,8 +3501,8 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp) 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; } @@ -3510,17 +3515,17 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp) 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); - utp->actions.push_back (xstrdup (p)); + utp->actions.emplace_back (xstrdup (p)); } else if (piece == 'S') { utp = get_uploaded_tp (num, addr, utpp); - utp->step_actions.push_back (xstrdup (p)); + utp->step_actions.emplace_back (xstrdup (p)); } else if (piece == 'Z') { @@ -3540,11 +3545,11 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp) 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:")) - utp->cmd_strings.push_back (xstrdup (buf)); + utp->cmd_strings.emplace_back (xstrdup (buf)); } else if (piece == 'V') { @@ -3643,23 +3648,23 @@ print_one_static_tracepoint_marker (int count, char wrap_indent[80]; char extra_field_indent[80]; struct ui_out *uiout = current_uiout; - VEC(breakpoint_p) *tracepoints; symtab_and_line sal; sal.pc = marker.address; - tracepoints = static_tracepoints_here (marker.address); + std::vector tracepoints + = static_tracepoints_here (marker.address); ui_out_emit_tuple tuple_emitter (uiout, "marker"); /* A counter field to help readability. This is not a stable identifier! */ - uiout->field_int ("count", count); + uiout->field_signed ("count", count); uiout->field_string ("marker-id", marker.str_id.c_str ()); uiout->field_fmt ("enabled", "%c", - !VEC_empty (breakpoint_p, tracepoints) ? 'y' : 'n'); + !tracepoints.empty () ? 'y' : 'n'); uiout->spaces (2); strcpy (wrap_indent, " "); @@ -3678,8 +3683,8 @@ print_one_static_tracepoint_marker (int count, if (sym) { uiout->text ("in "); - uiout->field_string ("func", - SYMBOL_PRINT_NAME (sym)); + uiout->field_string ("func", sym->print_name (), + function_name_style.style ()); uiout->wrap_hint (wrap_indent); uiout->text (" at "); } @@ -3689,7 +3694,8 @@ print_one_static_tracepoint_marker (int count, if (sal.symtab != NULL) { uiout->field_string ("file", - symtab_to_filename_for_display (sal.symtab)); + symtab_to_filename_for_display (sal.symtab), + file_name_style.style ()); uiout->text (":"); if (uiout->is_mi_like_p ()) @@ -3701,7 +3707,7 @@ print_one_static_tracepoint_marker (int count, else uiout->field_skip ("fullname"); - uiout->field_int ("line", sal.line); + uiout->field_signed ("line", sal.line); } else { @@ -3715,32 +3721,29 @@ print_one_static_tracepoint_marker (int count, uiout->field_string ("extra-data", marker.extra.c_str ()); uiout->text ("\"\n"); - if (!VEC_empty (breakpoint_p, tracepoints)) + if (!tracepoints.empty ()) { int ix; - struct breakpoint *b; { - ui_out_emit_tuple tuple_emitter (uiout, "tracepoints-at"); + ui_out_emit_tuple inner_tuple_emitter (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++) + for (ix = 0; ix < tracepoints.size (); ix++) { if (ix > 0) uiout->text (", "); uiout->text ("#"); - uiout->field_int ("tracepoint-id", b->number); + uiout->field_signed ("tracepoint-id", tracepoints[ix]->number); } } if (uiout->is_mi_like_p ()) - uiout->field_int ("number-of-tracepoints", - VEC_length(breakpoint_p, tracepoints)); + uiout->field_signed ("number-of-tracepoints", tracepoints.size ()); else uiout->text ("\n"); } - VEC_free (breakpoint_p, tracepoints); } static void @@ -3792,7 +3795,7 @@ sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var, { /* We need to read the whole object before we know its size. */ gdb::optional buf - = target_read_alloc (target_stack, TARGET_OBJECT_STATIC_TRACE_DATA, + = target_read_alloc (current_top_target (), TARGET_OBJECT_STATIC_TRACE_DATA, NULL); if (buf) { @@ -3973,6 +3976,9 @@ static const struct internalvar_funcs sdata_funcs = NULL }; +/* See tracepoint.h. */ +cmd_list_element *while_stepping_cmd_element = nullptr; + /* module initialization */ void _initialize_tracepoint (void) @@ -3989,7 +3995,7 @@ _initialize_tracepoint (void) tracepoint_number = -1; add_info ("scope", info_scope_command, - _("List the variables local to a scope")); + _("List the variables local to a scope.")); add_cmd ("tracepoints", class_trace, _("Tracing of program execution without stopping the program."), @@ -4012,27 +4018,25 @@ If no arguments are supplied, delete all variables."), &deletelist); /* FIXME add a trace variable completer. */ add_info ("tvariables", info_tvariables_command, _("\ -Status of trace state variables and their values.\n\ -")); +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, tfind_command, _("\ -Select a trace frame;\n\ +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, 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, 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, tfind_line_command, _("\ @@ -4084,7 +4088,8 @@ Entering \"end\" on a line by itself is the normal way to terminate\n\ 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\ @@ -4121,8 +4126,8 @@ depending on target's capabilities.")); 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); @@ -4162,22 +4167,22 @@ disables any attempt to set the buffer size and lets the target choose."), 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); }