/* Branch trace support for GDB, the GNU debugger.
- Copyright (C) 2013-2019 Free Software Foundation, Inc.
+ Copyright (C) 2013-2022 Free Software Foundation, Inc.
Contributed by Intel Corp. <markus.t.metzger@intel.com>
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;
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;
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);
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;
return;
}
- internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+ internal_error (__FILE__, __LINE__, _("Unknown branch trace format."));
}
static void
pc = regcache_read_pc (regcache);
btrace.format = BTRACE_FORMAT_BTS;
- btrace.variant.bts.blocks = new std::vector <btrace_block>;
+ btrace.variant.bts.blocks = new std::vector<btrace_block>;
btrace.variant.bts.blocks->emplace_back (pc, pc);
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).c_str ());
+ 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
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).c_str ());
+ 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).c_str ());
+ tp->ptid.to_string ().c_str ());
target_teardown_btrace (btp->target);
btp->target = NULL;
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;
int errcode;
DEBUG ("fetch thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid).c_str ());
+ 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_thread (tp));
struct btrace_thread_info *btinfo;
DEBUG ("clear thread %s (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid).c_str ());
+ tp->ptid.to_string ().c_str ());
/* Make sure btrace frames that may hold a pointer into the branch
trace data are destroyed. */
case BTRACE_FORMAT_NONE:
btrace->format = BTRACE_FORMAT_BTS;
- btrace->variant.bts.blocks = new std::vector <btrace_block>;
+ btrace->variant.bts.blocks = new std::vector<btrace_block>;
break;
default:
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 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:
{
- const std::vector <btrace_block> &blocks
+ const std::vector<btrace_block> &blocks
= *btinfo->data.variant.bts.blocks;
unsigned int 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;
struct btrace_thread_info *btinfo;
unsigned int size, begin, end, from, to;
- thread_info *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;
}
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
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: %zu.\n"),
- btinfo->data.variant.bts.blocks->size ());
+ 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, _("\