/* Branch trace support for GDB, the GNU debugger.
- Copyright (C) 2013-2019 Free Software Foundation, Inc.
+ Copyright (C) 2013-2020 Free Software Foundation, Inc.
Contributed by Intel Corp. <markus.t.metzger@intel.com>
#include "infrun.h"
#include "event-loop.h"
#include "inf-loop.h"
-#include "common/vec.h"
#include "inferior.h"
#include <algorithm>
+#include "gdbarch.h"
+#include "cli/cli-style.h"
static const target_info record_btrace_target_info = {
"record-btrace",
static void
record_btrace_enable_warn (struct thread_info *tp)
{
- TRY
+ try
{
btrace_enable (tp, &record_btrace_conf);
}
- CATCH (error, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &error)
{
warning ("%s", error.what ());
}
- END_CATCH
}
/* Enable automatic tracing of new threads. */
DEBUG ("info");
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
+ if (inferior_ptid == null_ptid)
error (_("No thread."));
+ tp = inferior_thread ();
+
validate_registers_access ();
btinfo = &tp->btrace;
if (!(format == BTRACE_FORMAT_PT && errcode > 0))
{
uiout->text (_("decode error ("));
- uiout->field_int ("errcode", errcode);
+ uiout->field_signed ("errcode", errcode);
uiout->text (_("): "));
}
uiout->text (errstr);
uiout->text (_("]\n"));
}
-/* Print an unsigned int. */
-
-static void
-ui_out_field_uint (struct ui_out *uiout, const char *fld, unsigned int val)
-{
- uiout->field_fmt (fld, "%u", val);
-}
-
/* A range of source lines. */
struct btrace_line_range
gdb::optional<ui_out_emit_tuple> src_and_asm_tuple;
gdb::optional<ui_out_emit_list> asm_list;
- gdb_pretty_print_disassembler disasm (gdbarch);
+ gdb_pretty_print_disassembler disasm (gdbarch, uiout);
for (btrace_insn_iterator it = *begin; btrace_insn_cmp (&it, end) != 0;
btrace_insn_next (&it, 1))
if ((insn->flags & BTRACE_INSN_FLAG_SPECULATIVE) != 0)
dinsn.is_speculative = 1;
- disasm.pretty_print_insn (uiout, &dinsn, flags);
+ disasm.pretty_print_insn (&dinsn, flags);
}
}
}
begin = bfun->insn_offset;
end = begin + size - 1;
- ui_out_field_uint (uiout, "insn begin", begin);
+ uiout->field_unsigned ("insn begin", begin);
uiout->text (",");
- ui_out_field_uint (uiout, "insn end", end);
+ uiout->field_unsigned ("insn end", end);
}
/* Compute the lowest and highest source line for the instructions in BFUN
uiout->field_string ("file",
symtab_to_filename_for_display (symbol_symtab (sym)),
- ui_out_style_kind::FILE);
+ file_name_style.style ());
btrace_compute_src_line_range (bfun, &begin, &end);
if (end < begin)
return;
uiout->text (":");
- uiout->field_int ("min line", begin);
+ uiout->field_signed ("min line", begin);
if (end == begin)
return;
uiout->text (",");
- uiout->field_int ("max line", end);
+ uiout->field_signed ("max line", end);
}
/* Get the name of a branch trace function. */
sym = bfun->sym;
if (sym != NULL)
- return SYMBOL_PRINT_NAME (sym);
+ return sym->print_name ();
else if (msym != NULL)
- return MSYMBOL_PRINT_NAME (msym);
+ return msym->print_name ();
else
return "??";
}
msym = bfun->msym;
/* Print the function index. */
- ui_out_field_uint (uiout, "index", bfun->number);
+ uiout->field_unsigned ("index", bfun->number);
uiout->text ("\t");
/* Indicate gaps in the trace. */
}
if (sym != NULL)
- uiout->field_string ("function", SYMBOL_PRINT_NAME (sym),
- ui_out_style_kind::FUNCTION);
+ uiout->field_string ("function", sym->print_name (),
+ function_name_style.style ());
else if (msym != NULL)
- uiout->field_string ("function", MSYMBOL_PRINT_NAME (msym),
- ui_out_style_kind::FUNCTION);
+ uiout->field_string ("function", msym->print_name (),
+ function_name_style.style ());
else if (!uiout->is_mi_like_p ())
uiout->field_string ("function", "??",
- ui_out_style_kind::FUNCTION);
+ function_name_style.style ());
if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
{
enum record_method
record_btrace_target::record_method (ptid_t ptid)
{
- struct thread_info * const tp = find_thread_ptid (ptid);
+ process_stratum_target *proc_target = current_inferior ()->process_target ();
+ thread_info *const tp = find_thread_ptid (proc_target, ptid);
if (tp == NULL)
error (_("No thread."));
bool
record_btrace_target::record_is_replaying (ptid_t ptid)
{
- for (thread_info *tp : all_non_exited_threads (ptid))
+ process_stratum_target *proc_target = current_inferior ()->process_target ();
+ for (thread_info *tp : all_non_exited_threads (proc_target, ptid))
if (btrace_is_replaying (tp))
return true;
if (section != NULL)
{
/* Check if the section we found is readonly. */
- if ((bfd_get_section_flags (section->the_bfd_section->owner,
- section->the_bfd_section)
+ if ((bfd_section_flags (section->the_bfd_section)
& SEC_READONLY) != 0)
{
/* Truncate the request to fit into this section. */
replay_memory_access = replay_memory_access_read_write;
ret = 0;
- TRY
+ try
{
ret = this->beneath ()->insert_breakpoint (gdbarch, bp_tgt);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
replay_memory_access = old;
- throw_exception (except);
+ throw;
}
- END_CATCH
replay_memory_access = old;
return ret;
replay_memory_access = replay_memory_access_read_write;
ret = 0;
- TRY
+ try
{
ret = this->beneath ()->remove_breakpoint (gdbarch, bp_tgt, reason);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
replay_memory_access = old;
- throw_exception (except);
+ throw;
}
- END_CATCH
replay_memory_access = old;
return ret;
void
record_btrace_target::fetch_registers (struct regcache *regcache, int regno)
{
- struct btrace_insn_iterator *replay;
- struct thread_info *tp;
-
- tp = find_thread_ptid (regcache->ptid ());
+ thread_info *tp = find_thread_ptid (regcache->target (), regcache->ptid ());
gdb_assert (tp != NULL);
- replay = tp->btrace.replay;
+ btrace_insn_iterator *replay = tp->btrace.replay;
if (replay != NULL && !record_btrace_generating_corefile)
{
const struct btrace_insn *insn;
&& record_is_replaying (regcache->ptid ()))
error (_("Cannot write registers while replaying."));
- gdb_assert (may_write_registers != 0);
+ gdb_assert (may_write_registers);
this->beneath ()->store_registers (regcache, regno);
}
}
/* btrace recording does not store previous memory content, neither the stack
- frames content. Any unwinding would return errorneous results as the stack
+ frames content. Any unwinding would return erroneous results as the stack
contents no longer matches the changed PC value restored from history.
Therefore this unwinder reports any possibly unwound registers as
<unavailable>. */
switch_to_thread (tp);
+ process_stratum_target *proc_target = tp->inf->process_target ();
+
/* Clear the executing flag to allow changes to the current frame.
We are not actually running, yet. We just started a reverse execution
command or a record goto command.
For the latter, EXECUTING is false and this has no effect.
For the former, EXECUTING is true and we're in wait, about to
move the thread. Since we need to recompute the stack, we temporarily
- set EXECUTING to flase. */
+ set EXECUTING to false. */
executing = tp->executing;
- set_executing (inferior_ptid, false);
+ set_executing (proc_target, inferior_ptid, false);
id = null_frame_id;
- TRY
+ try
{
id = get_frame_id (get_current_frame ());
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
/* Restore the previous execution state. */
- set_executing (inferior_ptid, executing);
+ set_executing (proc_target, inferior_ptid, executing);
- throw_exception (except);
+ throw;
}
- END_CATCH
/* Restore the previous execution state. */
- set_executing (inferior_ptid, executing);
+ set_executing (proc_target, inferior_ptid, executing);
return id;
}
Since frames are computed differently when we're replaying, we need to
recompute those stored frames and fix them up so we can still detect
subroutines after we started replaying. */
- TRY
+ try
{
struct frame_id frame_id;
int upd_step_frame_id, upd_step_stack_frame_id;
if (upd_step_stack_frame_id)
tp->control.step_stack_frame_id = frame_id;
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
xfree (btinfo->replay);
btinfo->replay = NULL;
registers_changed_thread (tp);
- throw_exception (except);
+ throw;
}
- END_CATCH
return replay;
}
record_btrace_wait below.
For all-stop targets, we only step INFERIOR_PTID and continue others. */
+
+ process_stratum_target *proc_target = current_inferior ()->process_target ();
+
if (!target_is_non_stop_p ())
{
gdb_assert (inferior_ptid.matches (ptid));
- for (thread_info *tp : all_non_exited_threads (ptid))
+ for (thread_info *tp : all_non_exited_threads (proc_target, ptid))
{
if (tp->ptid.matches (inferior_ptid))
record_btrace_resume_thread (tp, flag);
}
else
{
- for (thread_info *tp : all_non_exited_threads (ptid))
+ for (thread_info *tp : all_non_exited_threads (proc_target, ptid))
record_btrace_resume_thread (tp, flag);
}
}
/* Keep a work list of moving threads. */
- for (thread_info *tp : all_non_exited_threads (ptid))
+ process_stratum_target *proc_target = current_inferior ()->process_target ();
+ for (thread_info *tp : all_non_exited_threads (proc_target, ptid))
if ((tp->btrace.flags & (BTHR_MOVE | BTHR_STOP)) != 0)
moving.push_back (tp);
}
else
{
- for (thread_info *tp : all_non_exited_threads (ptid))
+ process_stratum_target *proc_target
+ = current_inferior ()->process_target ();
+
+ for (thread_info *tp : all_non_exited_threads (proc_target, ptid))
{
tp->btrace.flags &= ~BTHR_MOVE;
tp->btrace.flags |= BTHR_STOP;
record_btrace_conf.format = BTRACE_FORMAT_BTS;
- TRY
+ try
{
execute_command ("target record-btrace", from_tty);
}
- CATCH (exception, RETURN_MASK_ALL)
+ catch (const gdb_exception &exception)
{
record_btrace_conf.format = BTRACE_FORMAT_NONE;
- throw_exception (exception);
+ throw;
}
- END_CATCH
}
/* Start recording in Intel Processor Trace format. */
record_btrace_conf.format = BTRACE_FORMAT_PT;
- TRY
+ try
{
execute_command ("target record-btrace", from_tty);
}
- CATCH (exception, RETURN_MASK_ALL)
+ catch (const gdb_exception &exception)
{
record_btrace_conf.format = BTRACE_FORMAT_NONE;
- throw_exception (exception);
+ throw;
}
- END_CATCH
}
/* Alias for "target record". */
record_btrace_conf.format = BTRACE_FORMAT_PT;
- TRY
+ try
{
execute_command ("target record-btrace", from_tty);
}
- CATCH (exception, RETURN_MASK_ALL)
+ catch (const gdb_exception &exception)
{
record_btrace_conf.format = BTRACE_FORMAT_BTS;
- TRY
+ try
{
execute_command ("target record-btrace", from_tty);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
record_btrace_conf.format = BTRACE_FORMAT_NONE;
- throw_exception (ex);
+ throw;
}
- END_CATCH
}
- END_CATCH
}
/* The "set record btrace" command. */
add_alias_cmd ("pt", "btrace pt", class_obscure, 1, &record_cmdlist);
add_prefix_cmd ("btrace", class_support, cmd_set_record_btrace,
- _("Set record options"), &set_record_btrace_cmdlist,
+ _("Set record options."), &set_record_btrace_cmdlist,
"set record btrace ", 0, &set_record_cmdlist);
add_prefix_cmd ("btrace", class_support, cmd_show_record_btrace,
- _("Show record options"), &show_record_btrace_cmdlist,
+ _("Show record options."), &show_record_btrace_cmdlist,
"show record btrace ", 0, &show_record_cmdlist);
add_setshow_enum_cmd ("replay-memory-access", no_class,
workarounds for a similar cpu that GDB supports.\n\n\
When set to \"none\", errata workarounds are disabled."),
&set_record_btrace_cpu_cmdlist,
- _("set record btrace cpu "), 1,
+ "set record btrace cpu ", 1,
&set_record_btrace_cmdlist);
add_cmd ("auto", class_support, cmd_set_record_btrace_cpu_auto, _("\
&show_record_btrace_cmdlist);
add_prefix_cmd ("bts", class_support, cmd_set_record_btrace_bts,
- _("Set record btrace bts options"),
+ _("Set record btrace bts options."),
&set_record_btrace_bts_cmdlist,
"set record btrace bts ", 0, &set_record_btrace_cmdlist);
add_prefix_cmd ("bts", class_support, cmd_show_record_btrace_bts,
- _("Show record btrace bts options"),
+ _("Show record btrace bts options."),
&show_record_btrace_bts_cmdlist,
"show record btrace bts ", 0, &show_record_btrace_cmdlist);
&show_record_btrace_bts_cmdlist);
add_prefix_cmd ("pt", class_support, cmd_set_record_btrace_pt,
- _("Set record btrace pt options"),
+ _("Set record btrace pt options."),
&set_record_btrace_pt_cmdlist,
"set record btrace pt ", 0, &set_record_btrace_cmdlist);
add_prefix_cmd ("pt", class_support, cmd_show_record_btrace_pt,
- _("Show record btrace pt options"),
+ _("Show record btrace pt options."),
&show_record_btrace_pt_cmdlist,
"show record btrace pt ", 0, &show_record_btrace_cmdlist);