/* Branch trace support for GDB, the GNU debugger.
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2022 Free Software Foundation, Inc.
Contributed by Intel Corp. <markus.t.metzger@intel.com>
#include "filenames.h"
#include "xml-support.h"
#include "regcache.h"
-#include "rsp-low.h"
+#include "gdbsupport/rsp-low.h"
#include "gdbcmd.h"
#include "cli/cli-utils.h"
+#include "gdbarch.h"
/* For maintenance commands. */
#include "record-btrace.h"
static struct cmd_list_element *maint_btrace_pt_show_cmdlist;
/* Control whether to skip PAD packets when computing the packet history. */
-static int maint_btrace_pt_skip_pad = 1;
+static bool maint_btrace_pt_skip_pad = true;
static void btrace_add_pc (struct thread_info *tp);
do \
{ \
if (record_debug != 0) \
- fprintf_unfiltered (gdb_stdlog, \
+ fprintf_unfiltered (gdb_stdlog, \
"[btrace] " msg "\n", ##args); \
} \
while (0)
sym = bfun->sym;
if (sym != NULL)
- return SYMBOL_PRINT_NAME (sym);
+ return sym->print_name ();
if (msym != NULL)
- return MSYMBOL_PRINT_NAME (msym);
+ return msym->print_name ();
return "<unknown>";
}
/* If the minimal symbol changed, we certainly switched functions. */
if (mfun != NULL && msym != NULL
- && strcmp (MSYMBOL_LINKAGE_NAME (mfun), MSYMBOL_LINKAGE_NAME (msym)) != 0)
+ && strcmp (mfun->linkage_name (), msym->linkage_name ()) != 0)
return 1;
/* If the symbol changed, we certainly switched functions. */
const char *bfname, *fname;
/* Check the function name. */
- if (strcmp (SYMBOL_LINKAGE_NAME (fun), SYMBOL_LINKAGE_NAME (sym)) != 0)
+ if (strcmp (fun->linkage_name (), sym->linkage_name ()) != 0)
return 1;
/* Check the location of those functions, as well. */
static void
ftrace_update_caller (struct btrace_function *bfun,
struct btrace_function *caller,
- enum btrace_function_flag flags)
+ btrace_function_flags flags)
{
if (bfun->up != 0)
ftrace_debug (bfun, "updating caller");
ftrace_fixup_caller (struct btrace_thread_info *btinfo,
struct btrace_function *bfun,
struct btrace_function *caller,
- enum btrace_function_flag flags)
+ btrace_function_flags flags)
{
unsigned int prev, next;
if (start == pc)
return ftrace_new_tailcall (btinfo, mfun, fun);
+ /* Some versions of _Unwind_RaiseException use an indirect
+ jump to 'return' to the exception handler of the caller
+ handling the exception instead of a return. Let's restrict
+ this heuristic to that and related functions. */
+ const char *fname = ftrace_print_function_name (bfun);
+ if (strncmp (fname, "_Unwind_", strlen ("_Unwind_")) == 0)
+ {
+ struct btrace_function *caller
+ = ftrace_find_call_by_number (btinfo, bfun->up);
+ caller = ftrace_find_caller (btinfo, caller, mfun, fun);
+ if (caller != NULL)
+ return ftrace_new_return (btinfo, mfun, fun);
+ }
+
/* If we can't determine the function for PC, we treat a jump at
the end of the block as tail call if we're switching functions
and as an intra-function branch if we don't. */
enum btrace_insn_class iclass;
iclass = BTRACE_INSN_OTHER;
- TRY
+ try
{
if (gdbarch_insn_is_call (gdbarch, pc))
iclass = BTRACE_INSN_CALL;
else if (gdbarch_insn_is_jump (gdbarch, pc))
iclass = BTRACE_INSN_JUMP;
}
- CATCH (error, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &error)
{
}
- END_CATCH
return iclass;
}
best_r = NULL;
/* We search the back traces of LHS and RHS for valid connections and connect
- the two functon segments that give the longest combined back trace. */
+ the two function segments that give the longest combined back trace. */
for (cand_l = lhs; cand_l != NULL;
cand_l = ftrace_get_caller (btinfo, cand_l))
const struct btrace_data_bts *btrace,
std::vector<unsigned int> &gaps)
{
+ /* We may end up doing target calls that require the current thread to be TP,
+ for example reading memory through gdb_insn_length. Make sure TP is the
+ current thread. */
+ scoped_restore_current_thread restore_thread;
+ switch_to_thread (tp);
+
struct btrace_thread_info *btinfo;
struct gdbarch *gdbarch;
unsigned int blk;
gdbarch = target_gdbarch ();
btinfo = &tp->btrace;
- blk = VEC_length (btrace_block_s, btrace->blocks);
+ blk = btrace->blocks->size ();
if (btinfo->functions.empty ())
level = INT_MAX;
while (blk != 0)
{
- btrace_block_s *block;
CORE_ADDR pc;
blk -= 1;
- block = VEC_index (btrace_block_s, btrace->blocks, blk);
- pc = block->begin;
+ const btrace_block &block = btrace->blocks->at (blk);
+ pc = block.begin;
for (;;)
{
int size;
/* We should hit the end of the block. Warn if we went too far. */
- if (block->end < pc)
+ if (block.end < pc)
{
/* Indicate the gap in the trace. */
bfun = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW, gaps);
level = std::min (level, bfun->level);
size = 0;
- TRY
+ try
{
size = gdb_insn_length (gdbarch, pc);
}
- CATCH (error, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &error)
{
}
- END_CATCH
insn.pc = pc;
insn.size = size;
ftrace_update_insns (bfun, insn);
/* We're done once we pushed the instruction at the end. */
- if (block->end == pc)
+ if (block.end == pc)
break;
/* We can't continue if we fail to compute the size. */
break;
case ptev_enabled:
+ if (event.status_update != 0)
+ break;
+
if (event.variant.enabled.resumed == 0 && !btinfo->functions.empty ())
{
bfun = ftrace_new_gap (btinfo, BDE_PT_DISABLED, gaps);
int result, errcode;
result = (int) size;
- TRY
+ try
{
errcode = target_read_code ((CORE_ADDR) pc, buffer, size);
if (errcode != 0)
result = -pte_nomap;
}
- CATCH (error, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &error)
{
result = -pte_nomap;
}
- END_CATCH
return result;
}
const struct btrace_data_pt *btrace,
std::vector<unsigned int> &gaps)
{
+ /* We may end up doing target calls that require the current thread to be TP,
+ for example reading memory through btrace_pt_readmem_callback. Make sure
+ TP is the current thread. */
+ scoped_restore_current_thread restore_thread;
+ switch_to_thread (tp);
+
struct btrace_thread_info *btinfo;
struct pt_insn_decoder *decoder;
struct pt_config config;
if (decoder == NULL)
error (_("Failed to allocate the Intel Processor Trace decoder."));
- TRY
+ try
{
struct pt_image *image;
ftrace_add_pt (btinfo, decoder, &level, gaps);
}
- CATCH (error, RETURN_MASK_ALL)
+ catch (const gdb_exception &error)
{
/* Indicate a gap in the trace if we quit trace processing. */
if (error.reason == RETURN_QUIT && !btinfo->functions.empty ())
btrace_finalize_ftrace_pt (decoder, tp, level);
- throw_exception (error);
+ throw;
}
- END_CATCH
btrace_finalize_ftrace_pt (decoder, tp, level);
}
return;
}
- internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+ internal_error (__FILE__, __LINE__, _("Unknown branch trace format."));
}
static void
{
std::vector<unsigned int> gaps;
- TRY
+ try
{
btrace_compute_ftrace_1 (tp, btrace, cpu, gaps);
}
- CATCH (error, RETURN_MASK_ALL)
+ catch (const gdb_exception &error)
{
btrace_finalize_ftrace (tp, gaps);
- throw_exception (error);
+ throw;
}
- END_CATCH
btrace_finalize_ftrace (tp, gaps);
}
btrace_add_pc (struct thread_info *tp)
{
struct btrace_data btrace;
- struct btrace_block *block;
struct regcache *regcache;
- struct cleanup *cleanup;
CORE_ADDR pc;
- regcache = get_thread_regcache (tp->ptid);
+ regcache = get_thread_regcache (tp);
pc = regcache_read_pc (regcache);
- btrace_data_init (&btrace);
btrace.format = BTRACE_FORMAT_BTS;
- btrace.variant.bts.blocks = NULL;
+ btrace.variant.bts.blocks = new std::vector<btrace_block>;
- cleanup = make_cleanup_btrace_data (&btrace);
-
- block = VEC_safe_push (btrace_block_s, btrace.variant.bts.blocks, NULL);
- block->begin = pc;
- block->end = pc;
+ btrace.variant.bts.blocks->emplace_back (pc, pc);
btrace_compute_ftrace (tp, &btrace, NULL);
-
- do_cleanups (cleanup);
}
/* See btrace.h. */
btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
{
if (tp->btrace.target != NULL)
- return;
+ error (_("Recording already enabled on thread %s (%s)."),
+ print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
#if !defined (HAVE_LIBIPT)
if (conf->format == BTRACE_FORMAT_PT)
#endif /* !defined (HAVE_LIBIPT) */
DEBUG ("enable thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid));
+ tp->ptid.to_string ().c_str ());
tp->btrace.target = target_enable_btrace (tp->ptid, conf);
- /* We're done if we failed to enable tracing. */
if (tp->btrace.target == NULL)
- return;
+ error (_("Failed to enable recording on thread %s (%s)."),
+ print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
/* We need to undo the enable in case of errors. */
- TRY
+ try
{
/* Add an entry for the current PC so we start tracing from where we
enabled it.
This is not relevant for BTRACE_FORMAT_PT since the trace will already
start at the PC at which tracing was enabled. */
if (conf->format != BTRACE_FORMAT_PT
- && can_access_registers_ptid (tp->ptid))
+ && can_access_registers_thread (tp))
btrace_add_pc (tp);
}
- CATCH (exception, RETURN_MASK_ALL)
+ catch (const gdb_exception &exception)
{
btrace_disable (tp);
- throw_exception (exception);
+ throw;
}
- END_CATCH
}
/* See btrace.h. */
struct btrace_thread_info *btp = &tp->btrace;
if (btp->target == NULL)
- return;
+ error (_("Recording not enabled on thread %s (%s)."),
+ print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
DEBUG ("disable thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid));
+ tp->ptid.to_string ().c_str ());
target_disable_btrace (btp->target);
btp->target = NULL;
return;
DEBUG ("teardown thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid));
+ tp->ptid.to_string ().c_str ());
target_teardown_btrace (btp->target);
btp->target = NULL;
{
struct btrace_thread_info *btinfo;
struct btrace_function *last_bfun;
- btrace_block_s *first_new_block;
+ btrace_block *first_new_block;
btinfo = &tp->btrace;
gdb_assert (!btinfo->functions.empty ());
- gdb_assert (!VEC_empty (btrace_block_s, btrace->blocks));
+ gdb_assert (!btrace->blocks->empty ());
last_bfun = &btinfo->functions.back ();
of the new trace, though, since we can't fill in the start address.*/
if (last_bfun->insn.empty ())
{
- VEC_pop (btrace_block_s, btrace->blocks);
+ btrace->blocks->pop_back ();
return 0;
}
/* Beware that block trace starts with the most recent block, so the
chronologically first block in the new trace is the last block in
the new trace's block vector. */
- first_new_block = VEC_last (btrace_block_s, btrace->blocks);
+ first_new_block = &btrace->blocks->back ();
const btrace_insn &last_insn = last_bfun->insn.back ();
/* If the current PC at the end of the block is the same as in our current
entries.
In the second case, the delta trace vector should contain exactly one
entry for the partial block containing the current PC. Remove it. */
- if (first_new_block->end == last_insn.pc
- && VEC_length (btrace_block_s, btrace->blocks) == 1)
+ if (first_new_block->end == last_insn.pc && btrace->blocks->size () == 1)
{
- VEC_pop (btrace_block_s, btrace->blocks);
+ btrace->blocks->pop_back ();
return 0;
}
btrace_stitch_trace (struct btrace_data *btrace, struct thread_info *tp)
{
/* If we don't have trace, there's nothing to do. */
- if (btrace_data_empty (btrace))
+ if (btrace->empty ())
return 0;
switch (btrace->format)
return -1;
}
- internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+ internal_error (__FILE__, __LINE__, _("Unknown branch trace format."));
}
/* Clear the branch trace histories in BTINFO. */
#if defined (HAVE_LIBIPT)
case BTRACE_FORMAT_PT:
- xfree (btinfo->maint.variant.pt.packets);
+ delete btinfo->maint.variant.pt.packets;
btinfo->maint.variant.pt.packets = NULL;
btinfo->maint.variant.pt.packet_history.begin = 0;
struct btrace_thread_info *btinfo;
struct btrace_target_info *tinfo;
struct btrace_data btrace;
- struct cleanup *cleanup;
int errcode;
DEBUG ("fetch thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid));
+ tp->ptid.to_string ().c_str ());
btinfo = &tp->btrace;
tinfo = btinfo->target;
if (btinfo->replay != NULL)
return;
- /* With CLI usage, TP->PTID always equals INFERIOR_PTID here. Now that we
- can store a gdb.Record object in Python referring to a different thread
- than the current one, temporarily set INFERIOR_PTID. */
- scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
- inferior_ptid = tp->ptid;
+ /* With CLI usage, TP is always the current thread when we get here.
+ However, since we can also store a gdb.Record object in Python
+ referring to a different thread than the current one, we need to
+ temporarily set the current thread. */
+ scoped_restore_current_thread restore_thread;
+ switch_to_thread (tp);
/* We should not be called on running or exited threads. */
- gdb_assert (can_access_registers_ptid (tp->ptid));
-
- btrace_data_init (&btrace);
- cleanup = make_cleanup_btrace_data (&btrace);
+ gdb_assert (can_access_registers_thread (tp));
/* Let's first try to extend the trace we already have. */
if (!btinfo->functions.empty ())
errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_NEW);
/* If we got any new trace, discard what we have. */
- if (errcode == 0 && !btrace_data_empty (&btrace))
+ if (errcode == 0 && !btrace.empty ())
btrace_clear (tp);
}
error (_("Failed to read branch trace."));
/* Compute the trace, provided we have any. */
- if (!btrace_data_empty (&btrace))
+ if (!btrace.empty ())
{
/* Store the raw trace data. The stored data will be cleared in
btrace_clear, so we always append the new trace. */
btrace_clear_history (btinfo);
btrace_compute_ftrace (tp, &btrace, cpu);
}
-
- do_cleanups (cleanup);
}
/* See btrace.h. */
struct btrace_thread_info *btinfo;
DEBUG ("clear thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid));
+ tp->ptid.to_string ().c_str ());
/* Make sure btrace frames that may hold a pointer into the branch
trace data are destroyed. */
/* Must clear the maint data before - it depends on BTINFO->DATA. */
btrace_maint_clear (btinfo);
- btrace_data_clear (&btinfo->data);
+ btinfo->data.clear ();
btrace_clear_history (btinfo);
}
void
btrace_free_objfile (struct objfile *objfile)
{
- struct thread_info *tp;
-
DEBUG ("free objfile");
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
btrace_clear (tp);
}
std::vector<gdb_xml_value> &attributes)
{
struct btrace_data *btrace;
- struct btrace_block *block;
ULONGEST *begin, *end;
btrace = (struct btrace_data *) user_data;
case BTRACE_FORMAT_NONE:
btrace->format = BTRACE_FORMAT_BTS;
- btrace->variant.bts.blocks = NULL;
+ btrace->variant.bts.blocks = new std::vector<btrace_block>;
break;
default:
begin = (ULONGEST *) xml_find_attribute (attributes, "begin")->value.get ();
end = (ULONGEST *) xml_find_attribute (attributes, "end")->value.get ();
-
- block = VEC_safe_push (btrace_block_s, btrace->variant.bts.blocks, NULL);
- block->begin = *begin;
- block->end = *end;
+ btrace->variant.bts.blocks->emplace_back (*begin, *end);
}
/* Parse a "raw" xml record. */
parse_xml_raw (struct gdb_xml_parser *parser, const char *body_text,
gdb_byte **pdata, size_t *psize)
{
- struct cleanup *cleanup;
- gdb_byte *data, *bin;
+ gdb_byte *bin;
size_t len, size;
len = strlen (body_text);
size = len / 2;
- bin = data = (gdb_byte *) xmalloc (size);
- cleanup = make_cleanup (xfree, data);
+ gdb::unique_xmalloc_ptr<gdb_byte> data ((gdb_byte *) xmalloc (size));
+ bin = data.get ();
- /* We use hex encoding - see common/rsp-low.h. */
+ /* We use hex encoding - see gdbsupport/rsp-low.h. */
while (len > 0)
{
char hi, lo;
len -= 2;
}
- discard_cleanups (cleanup);
-
- *pdata = data;
+ *pdata = data.release ();
*psize = size;
}
void
parse_xml_btrace (struct btrace_data *btrace, const char *buffer)
{
- struct cleanup *cleanup;
- int errcode;
-
#if defined (HAVE_LIBEXPAT)
- btrace->format = BTRACE_FORMAT_NONE;
+ int errcode;
+ btrace_data result;
+ result.format = BTRACE_FORMAT_NONE;
- cleanup = make_cleanup_btrace_data (btrace);
errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd", btrace_elements,
- buffer, btrace);
+ buffer, &result);
if (errcode != 0)
error (_("Error parsing branch trace."));
/* Keep parse results. */
- discard_cleanups (cleanup);
+ *btrace = std::move (result);
#else /* !defined (HAVE_LIBEXPAT) */
void
parse_xml_btrace_conf (struct btrace_config *conf, const char *xml)
{
- int errcode;
-
#if defined (HAVE_LIBEXPAT)
+ int errcode;
errcode = gdb_xml_parse_quick (_("btrace-conf"), "btrace-conf.dtd",
btrace_conf_elements, xml, conf);
if (errcode != 0)
return btrace_insn_cmp (&begin, &end) == 0;
}
-/* Forward the cleanup request. */
-
-static void
-do_btrace_data_cleanup (void *arg)
-{
- btrace_data_fini ((struct btrace_data *) arg);
-}
-
-/* See btrace.h. */
-
-struct cleanup *
-make_cleanup_btrace_data (struct btrace_data *data)
-{
- return make_cleanup (do_btrace_data_cleanup, data);
-}
-
#if defined (HAVE_LIBIPT)
/* Print a single packet. */
switch (packet->type)
{
default:
- printf_unfiltered (("[??: %x]"), packet->type);
+ printf_filtered (("[??: %x]"), packet->type);
break;
case ppt_psb:
- printf_unfiltered (("psb"));
+ printf_filtered (("psb"));
break;
case ppt_psbend:
- printf_unfiltered (("psbend"));
+ printf_filtered (("psbend"));
break;
case ppt_pad:
- printf_unfiltered (("pad"));
+ printf_filtered (("pad"));
break;
case ppt_tip:
- printf_unfiltered (("tip %u: 0x%" PRIx64 ""),
- packet->payload.ip.ipc,
- packet->payload.ip.ip);
+ printf_filtered (("tip %u: 0x%" PRIx64 ""),
+ packet->payload.ip.ipc,
+ packet->payload.ip.ip);
break;
case ppt_tip_pge:
- printf_unfiltered (("tip.pge %u: 0x%" PRIx64 ""),
- packet->payload.ip.ipc,
- packet->payload.ip.ip);
+ printf_filtered (("tip.pge %u: 0x%" PRIx64 ""),
+ packet->payload.ip.ipc,
+ packet->payload.ip.ip);
break;
case ppt_tip_pgd:
- printf_unfiltered (("tip.pgd %u: 0x%" PRIx64 ""),
- packet->payload.ip.ipc,
- packet->payload.ip.ip);
+ printf_filtered (("tip.pgd %u: 0x%" PRIx64 ""),
+ packet->payload.ip.ipc,
+ packet->payload.ip.ip);
break;
case ppt_fup:
- printf_unfiltered (("fup %u: 0x%" PRIx64 ""),
- packet->payload.ip.ipc,
- packet->payload.ip.ip);
+ printf_filtered (("fup %u: 0x%" PRIx64 ""),
+ packet->payload.ip.ipc,
+ packet->payload.ip.ip);
break;
case ppt_tnt_8:
- printf_unfiltered (("tnt-8 %u: 0x%" PRIx64 ""),
- packet->payload.tnt.bit_size,
- packet->payload.tnt.payload);
+ printf_filtered (("tnt-8 %u: 0x%" PRIx64 ""),
+ packet->payload.tnt.bit_size,
+ packet->payload.tnt.payload);
break;
case ppt_tnt_64:
- printf_unfiltered (("tnt-64 %u: 0x%" PRIx64 ""),
- packet->payload.tnt.bit_size,
- packet->payload.tnt.payload);
+ printf_filtered (("tnt-64 %u: 0x%" PRIx64 ""),
+ packet->payload.tnt.bit_size,
+ packet->payload.tnt.payload);
break;
case ppt_pip:
- printf_unfiltered (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
- packet->payload.pip.nr ? (" nr") : (""));
+ printf_filtered (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
+ packet->payload.pip.nr ? (" nr") : (""));
break;
case ppt_tsc:
- printf_unfiltered (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
+ printf_filtered (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
break;
case ppt_cbr:
- printf_unfiltered (("cbr %u"), packet->payload.cbr.ratio);
+ printf_filtered (("cbr %u"), packet->payload.cbr.ratio);
break;
case ppt_mode:
switch (packet->payload.mode.leaf)
{
default:
- printf_unfiltered (("mode %u"), packet->payload.mode.leaf);
+ printf_filtered (("mode %u"), packet->payload.mode.leaf);
break;
case pt_mol_exec:
- printf_unfiltered (("mode.exec%s%s"),
- packet->payload.mode.bits.exec.csl
- ? (" cs.l") : (""),
- packet->payload.mode.bits.exec.csd
- ? (" cs.d") : (""));
+ printf_filtered (("mode.exec%s%s"),
+ packet->payload.mode.bits.exec.csl
+ ? (" cs.l") : (""),
+ packet->payload.mode.bits.exec.csd
+ ? (" cs.d") : (""));
break;
case pt_mol_tsx:
- printf_unfiltered (("mode.tsx%s%s"),
- packet->payload.mode.bits.tsx.intx
- ? (" intx") : (""),
- packet->payload.mode.bits.tsx.abrt
- ? (" abrt") : (""));
+ printf_filtered (("mode.tsx%s%s"),
+ packet->payload.mode.bits.tsx.intx
+ ? (" intx") : (""),
+ packet->payload.mode.bits.tsx.abrt
+ ? (" abrt") : (""));
break;
}
break;
case ppt_ovf:
- printf_unfiltered (("ovf"));
+ printf_filtered (("ovf"));
break;
case ppt_stop:
- printf_unfiltered (("stop"));
+ printf_filtered (("stop"));
break;
case ppt_vmcs:
- printf_unfiltered (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
+ printf_filtered (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
break;
case ppt_tma:
- printf_unfiltered (("tma %x %x"), packet->payload.tma.ctc,
- packet->payload.tma.fc);
+ printf_filtered (("tma %x %x"), packet->payload.tma.ctc,
+ packet->payload.tma.fc);
break;
case ppt_mtc:
- printf_unfiltered (("mtc %x"), packet->payload.mtc.ctc);
+ printf_filtered (("mtc %x"), packet->payload.mtc.ctc);
break;
case ppt_cyc:
- printf_unfiltered (("cyc %" PRIx64 ""), packet->payload.cyc.value);
+ printf_filtered (("cyc %" PRIx64 ""), packet->payload.cyc.value);
break;
case ppt_mnt:
- printf_unfiltered (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
+ printf_filtered (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
break;
}
}
{
int errcode;
+ if (maint->variant.pt.packets == NULL)
+ maint->variant.pt.packets = new std::vector<btrace_pt_packet>;
+
for (;;)
{
struct btrace_pt_packet packet;
if (maint_btrace_pt_skip_pad == 0 || packet.packet.type != ppt_pad)
{
packet.errcode = pt_errcode (errcode);
- VEC_safe_push (btrace_pt_packet_s, maint->variant.pt.packets,
- &packet);
+ maint->variant.pt.packets->push_back (packet);
}
}
break;
packet.errcode = pt_errcode (errcode);
- VEC_safe_push (btrace_pt_packet_s, maint->variant.pt.packets,
- &packet);
+ maint->variant.pt.packets->push_back (packet);
warning (_("Error at trace offset 0x%" PRIx64 ": %s."),
packet.offset, pt_errstr (packet.errcode));
if (decoder == NULL)
error (_("Failed to allocate the Intel Processor Trace decoder."));
- TRY
+ try
{
btrace_maint_decode_pt (&btinfo->maint, decoder);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
pt_pkt_free_decoder (decoder);
if (except.reason < 0)
- throw_exception (except);
+ throw;
}
- END_CATCH
pt_pkt_free_decoder (decoder);
}
case BTRACE_FORMAT_BTS:
/* Nothing to do - we operate directly on BTINFO->DATA. */
*begin = 0;
- *end = VEC_length (btrace_block_s, btinfo->data.variant.bts.blocks);
+ *end = btinfo->data.variant.bts.blocks->size ();
*from = btinfo->maint.variant.bts.packet_history.begin;
*to = btinfo->maint.variant.bts.packet_history.end;
break;
#if defined (HAVE_LIBIPT)
case BTRACE_FORMAT_PT:
- if (VEC_empty (btrace_pt_packet_s, btinfo->maint.variant.pt.packets))
+ if (btinfo->maint.variant.pt.packets == nullptr)
+ btinfo->maint.variant.pt.packets = new std::vector<btrace_pt_packet>;
+
+ if (btinfo->maint.variant.pt.packets->empty ())
btrace_maint_update_pt_packets (btinfo);
*begin = 0;
- *end = VEC_length (btrace_pt_packet_s, btinfo->maint.variant.pt.packets);
+ *end = btinfo->maint.variant.pt.packets->size ();
*from = btinfo->maint.variant.pt.packet_history.begin;
*to = btinfo->maint.variant.pt.packet_history.end;
break;
case BTRACE_FORMAT_BTS:
{
- VEC (btrace_block_s) *blocks;
+ const std::vector<btrace_block> &blocks
+ = *btinfo->data.variant.bts.blocks;
unsigned int blk;
- blocks = btinfo->data.variant.bts.blocks;
for (blk = begin; blk < end; ++blk)
{
- const btrace_block_s *block;
-
- block = VEC_index (btrace_block_s, blocks, blk);
+ const btrace_block &block = blocks.at (blk);
- printf_unfiltered ("%u\tbegin: %s, end: %s\n", blk,
- core_addr_to_string_nz (block->begin),
- core_addr_to_string_nz (block->end));
+ printf_filtered ("%u\tbegin: %s, end: %s\n", blk,
+ core_addr_to_string_nz (block.begin),
+ core_addr_to_string_nz (block.end));
}
btinfo->maint.variant.bts.packet_history.begin = begin;
#if defined (HAVE_LIBIPT)
case BTRACE_FORMAT_PT:
{
- VEC (btrace_pt_packet_s) *packets;
+ const std::vector<btrace_pt_packet> &packets
+ = *btinfo->maint.variant.pt.packets;
unsigned int pkt;
- packets = btinfo->maint.variant.pt.packets;
for (pkt = begin; pkt < end; ++pkt)
{
- const struct btrace_pt_packet *packet;
+ const struct btrace_pt_packet &packet = packets.at (pkt);
- packet = VEC_index (btrace_pt_packet_s, packets, pkt);
+ printf_filtered ("%u\t", pkt);
+ printf_filtered ("0x%" PRIx64 "\t", packet.offset);
- printf_unfiltered ("%u\t", pkt);
- printf_unfiltered ("0x%" PRIx64 "\t", packet->offset);
-
- if (packet->errcode == pte_ok)
- pt_print_packet (&packet->packet);
+ if (packet.errcode == pte_ok)
+ pt_print_packet (&packet.packet);
else
- printf_unfiltered ("[error: %s]", pt_errstr (packet->errcode));
+ printf_filtered ("[error: %s]", pt_errstr (packet.errcode));
- printf_unfiltered ("\n");
+ printf_filtered ("\n");
}
btinfo->maint.variant.pt.packet_history.begin = begin;
maint_btrace_packet_history_cmd (const char *arg, int from_tty)
{
struct btrace_thread_info *btinfo;
- struct thread_info *tp;
unsigned int size, begin, end, from, to;
- tp = find_thread_ptid (inferior_ptid);
+ thread_info *tp = find_thread_ptid (current_inferior (), inferior_ptid);
if (tp == NULL)
error (_("No thread."));
btrace_maint_update_packets (btinfo, &begin, &end, &from, &to);
if (begin == end)
{
- printf_unfiltered (_("No trace.\n"));
+ printf_filtered (_("No trace.\n"));
return;
}
static void
maint_btrace_clear_packet_history_cmd (const char *args, int from_tty)
{
- struct btrace_thread_info *btinfo;
- struct thread_info *tp;
-
if (args != NULL && *args != 0)
error (_("Invalid argument."));
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
+ if (inferior_ptid == null_ptid)
error (_("No thread."));
- btinfo = &tp->btrace;
+ thread_info *tp = inferior_thread ();
+ btrace_thread_info *btinfo = &tp->btrace;
/* Must clear the maint data before - it depends on BTINFO->DATA. */
btrace_maint_clear (btinfo);
- btrace_data_clear (&btinfo->data);
+ btinfo->data.clear ();
}
/* The "maintenance btrace clear" command. */
static void
maint_btrace_clear_cmd (const char *args, int from_tty)
{
- struct thread_info *tp;
-
if (args != NULL && *args != 0)
error (_("Invalid argument."));
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
+ if (inferior_ptid == null_ptid)
error (_("No thread."));
+ thread_info *tp = inferior_thread ();
btrace_clear (tp);
}
-/* The "maintenance btrace" command. */
-
-static void
-maint_btrace_cmd (const char *args, int from_tty)
-{
- help_list (maint_btrace_cmdlist, "maintenance btrace ", all_commands,
- gdb_stdout);
-}
-
-/* The "maintenance set btrace" command. */
-
-static void
-maint_btrace_set_cmd (const char *args, int from_tty)
-{
- help_list (maint_btrace_set_cmdlist, "maintenance set btrace ", all_commands,
- gdb_stdout);
-}
-
-/* The "maintenance show btrace" command. */
-
-static void
-maint_btrace_show_cmd (const char *args, int from_tty)
-{
- help_list (maint_btrace_show_cmdlist, "maintenance show btrace ",
- all_commands, gdb_stdout);
-}
-
-/* The "maintenance set btrace pt" command. */
-
-static void
-maint_btrace_pt_set_cmd (const char *args, int from_tty)
-{
- help_list (maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
- all_commands, gdb_stdout);
-}
-
-/* The "maintenance show btrace pt" command. */
-
-static void
-maint_btrace_pt_show_cmd (const char *args, int from_tty)
-{
- help_list (maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
- all_commands, gdb_stdout);
-}
-
/* The "maintenance info btrace" command. */
static void
maint_info_btrace_cmd (const char *args, int from_tty)
{
struct btrace_thread_info *btinfo;
- struct thread_info *tp;
const struct btrace_config *conf;
if (args != NULL && *args != 0)
error (_("Invalid argument."));
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
+ if (inferior_ptid == null_ptid)
error (_("No thread."));
+ thread_info *tp = inferior_thread ();
+
btinfo = &tp->btrace;
conf = btrace_conf (btinfo);
if (conf == NULL)
error (_("No btrace configuration."));
- printf_unfiltered (_("Format: %s.\n"),
- btrace_format_string (conf->format));
+ printf_filtered (_("Format: %s.\n"),
+ btrace_format_string (conf->format));
switch (conf->format)
{
break;
case BTRACE_FORMAT_BTS:
- printf_unfiltered (_("Number of packets: %u.\n"),
- VEC_length (btrace_block_s,
- btinfo->data.variant.bts.blocks));
+ printf_filtered (_("Number of packets: %zu.\n"),
+ btinfo->data.variant.bts.blocks->size ());
break;
#if defined (HAVE_LIBIPT)
struct pt_version version;
version = pt_library_version ();
- printf_unfiltered (_("Version: %u.%u.%u%s.\n"), version.major,
- version.minor, version.build,
- version.ext != NULL ? version.ext : "");
+ printf_filtered (_("Version: %u.%u.%u%s.\n"), version.major,
+ version.minor, version.build,
+ version.ext != NULL ? version.ext : "");
btrace_maint_update_pt_packets (btinfo);
- printf_unfiltered (_("Number of packets: %u.\n"),
- VEC_length (btrace_pt_packet_s,
- btinfo->maint.variant.pt.packets));
+ printf_filtered (_("Number of packets: %zu.\n"),
+ ((btinfo->maint.variant.pt.packets == nullptr)
+ ? 0 : btinfo->maint.variant.pt.packets->size ()));
}
break;
#endif /* defined (HAVE_LIBIPT) */
/* Initialize btrace maintenance commands. */
+void _initialize_btrace ();
void
-_initialize_btrace (void)
+_initialize_btrace ()
{
add_cmd ("btrace", class_maintenance, maint_info_btrace_cmd,
_("Info about branch tracing data."), &maintenanceinfolist);
- add_prefix_cmd ("btrace", class_maintenance, maint_btrace_cmd,
- _("Branch tracing maintenance commands."),
- &maint_btrace_cmdlist, "maintenance btrace ",
- 0, &maintenancelist);
-
- add_prefix_cmd ("btrace", class_maintenance, maint_btrace_set_cmd, _("\
-Set branch tracing specific variables."),
- &maint_btrace_set_cmdlist, "maintenance set btrace ",
- 0, &maintenance_set_cmdlist);
-
- add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_set_cmd, _("\
-Set Intel Processor Trace specific variables."),
- &maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
- 0, &maint_btrace_set_cmdlist);
-
- add_prefix_cmd ("btrace", class_maintenance, maint_btrace_show_cmd, _("\
-Show branch tracing specific variables."),
- &maint_btrace_show_cmdlist, "maintenance show btrace ",
- 0, &maintenance_show_cmdlist);
-
- add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_show_cmd, _("\
-Show Intel Processor Trace specific variables."),
- &maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
- 0, &maint_btrace_show_cmdlist);
+ add_basic_prefix_cmd ("btrace", class_maintenance,
+ _("Branch tracing maintenance commands."),
+ &maint_btrace_cmdlist, 0, &maintenancelist);
+
+ add_setshow_prefix_cmd ("btrace", class_maintenance,
+ _("Set branch tracing specific variables."),
+ _("Show branch tracing specific variables."),
+ &maint_btrace_set_cmdlist,
+ &maint_btrace_show_cmdlist,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
+
+ add_setshow_prefix_cmd ("pt", class_maintenance,
+ _("Set Intel Processor Trace specific variables."),
+ _("Show Intel Processor Trace specific variables."),
+ &maint_btrace_pt_set_cmdlist,
+ &maint_btrace_pt_show_cmdlist,
+ &maint_btrace_set_cmdlist,
+ &maint_btrace_show_cmdlist);
add_setshow_boolean_cmd ("skip-pad", class_maintenance,
&maint_btrace_pt_skip_pad, _("\
Two arguments with comma between specify starting and ending packets to \
print.\n\
Preceded with '+'/'-' the second argument specifies the distance from the \
-first.\n"),
+first."),
&maint_btrace_cmdlist);
add_cmd ("clear-packet-history", class_maintenance,
maint_btrace_clear_packet_history_cmd,
_("Clears the branch tracing packet history.\n\
-Discards the raw branch tracing data but not the execution history data.\n\
-"),
+Discards the raw branch tracing data but not the execution history data."),
&maint_btrace_cmdlist);
add_cmd ("clear", class_maintenance, maint_btrace_clear_cmd,
_("Clears the branch tracing data.\n\
Discards the raw branch tracing data and the execution history data.\n\
-The next 'record' command will fetch the branch tracing data anew.\n\
-"),
+The next 'record' command will fetch the branch tracing data anew."),
&maint_btrace_cmdlist);
}