/* Branch trace support for GDB, the GNU debugger.
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 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"
#include <inttypes.h>
#include <ctype.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);
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. */
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))
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. */
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;
}
config.begin = btrace->data;
config.end = btrace->data + btrace->size;
- config.cpu.vendor = pt_translate_cpu_vendor (btrace->config.cpu.vendor);
- config.cpu.family = btrace->config.cpu.family;
- config.cpu.model = btrace->config.cpu.model;
- config.cpu.stepping = btrace->config.cpu.stepping;
+ /* We treat an unknown vendor as 'no errata'. */
+ if (btrace->config.cpu.vendor != CV_UNKNOWN)
+ {
+ config.cpu.vendor
+ = pt_translate_cpu_vendor (btrace->config.cpu.vendor);
+ config.cpu.family = btrace->config.cpu.family;
+ config.cpu.model = btrace->config.cpu.model;
+ config.cpu.stepping = btrace->config.cpu.stepping;
- errcode = pt_cpu_errata (&config.errata, &config.cpu);
- if (errcode < 0)
- error (_("Failed to configure the Intel Processor Trace decoder: %s."),
- pt_errstr (pt_errcode (errcode)));
+ errcode = pt_cpu_errata (&config.errata, &config.cpu);
+ if (errcode < 0)
+ error (_("Failed to configure the Intel Processor Trace "
+ "decoder: %s."), pt_errstr (pt_errcode (errcode)));
+ }
decoder = pt_insn_alloc_decoder (&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);
}
#endif /* defined (HAVE_LIBIPT) */
/* Compute the function branch trace from a block branch trace BTRACE for
- a thread given by BTINFO. */
+ a thread given by BTINFO. If CPU is not NULL, overwrite the cpu in the
+ branch trace configuration. This is currently only used for the PT
+ format. */
static void
-btrace_compute_ftrace_1 (struct thread_info *tp, struct btrace_data *btrace,
+btrace_compute_ftrace_1 (struct thread_info *tp,
+ struct btrace_data *btrace,
+ const struct btrace_cpu *cpu,
std::vector<unsigned int> &gaps)
{
DEBUG ("compute ftrace");
return;
case BTRACE_FORMAT_PT:
+ /* Overwrite the cpu we use for enabling errata workarounds. */
+ if (cpu != nullptr)
+ btrace->variant.pt.config.cpu = *cpu;
+
btrace_compute_ftrace_pt (tp, &btrace->variant.pt, gaps);
return;
}
}
static void
-btrace_compute_ftrace (struct thread_info *tp, struct btrace_data *btrace)
+btrace_compute_ftrace (struct thread_info *tp, struct btrace_data *btrace,
+ const struct btrace_cpu *cpu)
{
std::vector<unsigned int> gaps;
- TRY
+ try
{
- btrace_compute_ftrace_1 (tp, btrace, gaps);
+ 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;
-
- 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 = new std::vector<btrace_block>;
- btrace_compute_ftrace (tp, &btrace);
+ btrace.variant.bts.blocks->emplace_back (pc, pc);
- do_cleanups (cleanup);
+ btrace_compute_ftrace (tp, &btrace, NULL);
}
/* See btrace.h. */
#endif /* !defined (HAVE_LIBIPT) */
DEBUG ("enable thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
tp->btrace.target = target_enable_btrace (tp->ptid, conf);
return;
/* 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. */
return;
DEBUG ("disable thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).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));
+ target_pid_to_str (tp->ptid).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)
#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;
/* See btrace.h. */
void
-btrace_fetch (struct thread_info *tp)
+btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
{
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));
+ target_pid_to_str (tp->ptid).c_str ());
btinfo = &tp->btrace;
tinfo = btinfo->target;
inferior_ptid = tp->ptid;
/* 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_maint_clear (btinfo);
btrace_clear_history (btinfo);
- btrace_compute_ftrace (tp, &btrace);
+ 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));
+ target_pid_to_str (tp->ptid).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. */
{
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));
btrace_maint_update_pt_packets (struct btrace_thread_info *btinfo)
{
struct pt_packet_decoder *decoder;
+ const struct btrace_cpu *cpu;
struct btrace_data_pt *pt;
struct pt_config config;
int errcode;
config.begin = pt->data;
config.end = pt->data + pt->size;
- config.cpu.vendor = pt_translate_cpu_vendor (pt->config.cpu.vendor);
- config.cpu.family = pt->config.cpu.family;
- config.cpu.model = pt->config.cpu.model;
- config.cpu.stepping = pt->config.cpu.stepping;
+ cpu = record_btrace_get_cpu ();
+ if (cpu == nullptr)
+ cpu = &pt->config.cpu;
+
+ /* We treat an unknown vendor as 'no errata'. */
+ if (cpu->vendor != CV_UNKNOWN)
+ {
+ config.cpu.vendor = pt_translate_cpu_vendor (cpu->vendor);
+ config.cpu.family = cpu->family;
+ config.cpu.model = cpu->model;
+ config.cpu.stepping = cpu->stepping;
- errcode = pt_cpu_errata (&config.errata, &config.cpu);
- if (errcode < 0)
- error (_("Failed to configure the Intel Processor Trace decoder: %s."),
- pt_errstr (pt_errcode (errcode)));
+ errcode = pt_cpu_errata (&config.errata, &config.cpu);
+ if (errcode < 0)
+ error (_("Failed to configure the Intel Processor Trace "
+ "decoder: %s."), pt_errstr (pt_errcode (errcode)));
+ }
decoder = pt_pkt_alloc_decoder (&config);
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));
+ 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;
-
- packet = VEC_index (btrace_pt_packet_s, packets, pkt);
+ const struct btrace_pt_packet &packet = packets.at (pkt);
printf_unfiltered ("%u\t", pkt);
- printf_unfiltered ("0x%" PRIx64 "\t", packet->offset);
+ 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_unfiltered ("[error: %s]", pt_errstr (packet.errcode));
printf_unfiltered ("\n");
}
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 (inferior_ptid);
if (tp == NULL)
error (_("No thread."));
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);
}
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);
break;
case BTRACE_FORMAT_BTS:
- printf_unfiltered (_("Number of packets: %u.\n"),
- VEC_length (btrace_block_s,
- btinfo->data.variant.bts.blocks));
+ printf_unfiltered (_("Number of packets: %zu.\n"),
+ btinfo->data.variant.bts.blocks->size ());
break;
#if defined (HAVE_LIBIPT)
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_unfiltered (_("Number of packets: %zu.\n"),
+ ((btinfo->maint.variant.pt.packets == nullptr)
+ ? 0 : btinfo->maint.variant.pt.packets->size ()));
}
break;
#endif /* defined (HAVE_LIBIPT) */
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);
}