/* 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 "infrun.h"
#include "event-loop.h"
#include "inf-loop.h"
-#include "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",
+ N_("Branch tracing target"),
+ N_("Collect control-flow trace and provide the execution history.")
+};
/* The target_ops of record-btrace. */
class record_btrace_target final : public target_ops
{
public:
- record_btrace_target ()
- { to_stratum = record_stratum; }
-
- const char *shortname () override
- { return "record-btrace"; }
-
- const char *longname () override
- { return _("Branch tracing target"); }
+ const target_info &info () const override
+ { return record_btrace_target_info; }
- const char *doc () override
- { return _("Collect control-flow trace and provide the execution history."); }
+ strata stratum () const override { return record_stratum; }
- void open (const char *, int) override;
void close () override;
void async (int) override;
void call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
override;
- int record_is_replaying (ptid_t ptid) override;
- int record_will_replay (ptid_t ptid, int dir) override;
+ bool record_is_replaying (ptid_t ptid) override;
+ bool record_will_replay (ptid_t ptid, int dir) override;
void record_stop_replaying () override;
enum target_xfer_status xfer_partial (enum target_object object,
void stop (ptid_t) override;
void update_thread_list () override;
- int thread_alive (ptid_t ptid) override;
+ bool thread_alive (ptid_t ptid) override;
void goto_record_begin () override;
void goto_record_end () override;
void goto_record (ULONGEST insn) override;
- int can_execute_reverse () override;
+ bool can_execute_reverse () override;
- int stopped_by_sw_breakpoint () override;
- int supports_stopped_by_sw_breakpoint () override;
+ bool stopped_by_sw_breakpoint () override;
+ bool supports_stopped_by_sw_breakpoint () override;
- int stopped_by_hw_breakpoint () override;
- int supports_stopped_by_hw_breakpoint () override;
+ bool stopped_by_hw_breakpoint () override;
+ bool supports_stopped_by_hw_breakpoint () override;
enum exec_direction_kind execution_direction () override;
void prepare_to_generate_core () override;
/* Token associated with a new-thread observer enabling branch tracing
for the new thread. */
-static const gdb::observers::token record_btrace_thread_observer_token;
+static const gdb::observers::token record_btrace_thread_observer_token {};
/* Memory access types used in set/show record btrace replay-memory-access. */
static const char replay_memory_access_read_only[] = "read-only";
static struct thread_info *
require_btrace_thread (void)
{
- struct thread_info *tp;
-
DEBUG ("require");
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
+ if (inferior_ptid == null_ptid)
error (_("No thread."));
+ thread_info *tp = inferior_thread ();
+
validate_registers_access ();
btrace_fetch (tp, record_btrace_get_cpu ());
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.message);
+ warning ("%s", error.what ());
}
- END_CATCH
}
/* Enable automatic tracing of new threads. */
std::forward_list<thread_info *> m_threads;
};
-/* The open method of target record-btrace. */
+/* Open target record-btrace. */
-void
-record_btrace_target::open (const char *args, int from_tty)
+static void
+record_btrace_target_open (const char *args, int from_tty)
{
/* If we fail to enable btrace for one thread, disable it for the threads for
which it was successfully enabled. */
scoped_btrace_disable btrace_disable;
- struct thread_info *tp;
DEBUG ("open");
if (!target_has_execution)
error (_("The program is not being run."));
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
if (args == NULL || *args == 0 || number_is_in_list (args, tp->global_num))
{
btrace_enable (tp, &record_btrace_conf);
void
record_btrace_target::stop_recording ()
{
- struct thread_info *tp;
-
DEBUG ("stop recording");
record_btrace_auto_disable ();
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
if (tp->btrace.target != NULL)
btrace_disable (tp);
}
record_btrace_target::disconnect (const char *args,
int from_tty)
{
- struct target_ops *beneath = this->beneath;
+ struct target_ops *beneath = this->beneath ();
/* Do not stop recording, just clean up GDB side. */
unpush_target (this);
void
record_btrace_target::close ()
{
- struct thread_info *tp;
-
if (record_btrace_async_inferior_event_handler != NULL)
delete_async_event_handler (&record_btrace_async_inferior_event_handler);
/* We should have already stopped recording.
Tear down btrace in case we have not. */
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
btrace_teardown (tp);
}
else
clear_async_event_handler (record_btrace_async_inferior_event_handler);
- this->beneath->async (enable);
+ this->beneath ()->async (enable);
}
/* Adjusts the size and returns a human readable size suffix. */
printf_unfiltered (_("Recorded %u instructions in %u functions (%u gaps) "
"for thread %s (%s).\n"), insns, calls, gaps,
- print_thread_id (tp), target_pid_to_str (tp->ptid));
+ print_thread_id (tp),
+ target_pid_to_str (tp->ptid).c_str ());
if (btrace_is_replaying (tp))
printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
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
return;
uiout->field_string ("file",
- symtab_to_filename_for_display (symbol_symtab (sym)));
+ symtab_to_filename_for_display (symbol_symtab (sym)),
+ 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));
+ uiout->field_string ("function", sym->print_name (),
+ function_name_style.style ());
else if (msym != NULL)
- uiout->field_string ("function", MSYMBOL_PRINT_NAME (msym));
+ uiout->field_string ("function", msym->print_name (),
+ function_name_style.style ());
else if (!uiout->is_mi_like_p ())
- uiout->field_string ("function", "??");
+ uiout->field_string ("function", "??",
+ function_name_style.style ());
if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
{
/* The record_is_replaying method of target record-btrace. */
-int
+bool
record_btrace_target::record_is_replaying (ptid_t ptid)
{
- struct thread_info *tp;
-
- ALL_NON_EXITED_THREADS (tp)
- if (ptid_match (tp->ptid, ptid) && btrace_is_replaying (tp))
- return 1;
+ for (thread_info *tp : all_non_exited_threads (ptid))
+ if (btrace_is_replaying (tp))
+ return true;
- return 0;
+ return false;
}
/* The record_will_replay method of target record-btrace. */
-int
+bool
record_btrace_target::record_will_replay (ptid_t ptid, int dir)
{
return dir == EXEC_REVERSE || record_is_replaying (ptid);
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. */
}
/* Forward the request. */
- return this->beneath->xfer_partial (object, annex, readbuf, writebuf,
- offset, len, xfered_len);
+ return this->beneath ()->xfer_partial (object, annex, readbuf, writebuf,
+ offset, len, xfered_len);
}
/* The insert_breakpoint method of target record-btrace. */
replay_memory_access = replay_memory_access_read_write;
ret = 0;
- TRY
+ try
{
- ret = this->beneath->insert_breakpoint (gdbarch, bp_tgt);
+ 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);
+ 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;
struct btrace_insn_iterator *replay;
struct thread_info *tp;
- tp = find_thread_ptid (regcache_get_ptid (regcache));
+ tp = find_thread_ptid (regcache->ptid ());
gdb_assert (tp != NULL);
replay = tp->btrace.replay;
insn = btrace_insn_get (replay);
gdb_assert (insn != NULL);
- regcache_raw_supply (regcache, regno, &insn->pc);
+ regcache->raw_supply (regno, &insn->pc);
}
else
- this->beneath->fetch_registers (regcache, regno);
+ this->beneath ()->fetch_registers (regcache, regno);
}
/* The store_registers method of target record-btrace. */
void
record_btrace_target::store_registers (struct regcache *regcache, int regno)
{
- struct target_ops *t;
-
if (!record_btrace_generating_corefile
- && record_is_replaying (regcache_get_ptid (regcache)))
+ && 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);
+ this->beneath ()->store_registers (regcache, regno);
}
/* The prepare_to_store method of target record-btrace. */
record_btrace_target::prepare_to_store (struct regcache *regcache)
{
if (!record_btrace_generating_corefile
- && record_is_replaying (regcache_get_ptid (regcache)))
+ && record_is_replaying (regcache->ptid ()))
return;
- this->beneath->prepare_to_store (regcache);
+ this->beneath ()->prepare_to_store (regcache);
}
/* The branch trace frame cache. */
struct frame_info *next;
/* THIS_FRAME does not contain a reference to its thread. */
- tp = find_thread_ptid (inferior_ptid);
- gdb_assert (tp != NULL);
+ tp = inferior_thread ();
bfun = NULL;
next = get_next_frame (this_frame);
if ((callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
return 0;
- tinfo = find_thread_ptid (inferior_ptid);
+ tinfo = inferior_thread ();
if (btrace_find_call_by_number (&it, &tinfo->btrace, callee->up) == 0)
return 0;
}
/* 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>. */
struct btrace_thread_info *btinfo;
DEBUG ("resuming thread %s (%s): %x (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid), flag, btrace_thread_flag_to_str (flag));
+ target_pid_to_str (tp->ptid).c_str (), flag,
+ btrace_thread_flag_to_str (flag));
btinfo = &tp->btrace;
/* Get the current frame for TP. */
-static struct frame_info *
-get_thread_current_frame (struct thread_info *tp)
+static struct frame_id
+get_thread_current_frame_id (struct thread_info *tp)
{
- struct frame_info *frame;
- ptid_t old_inferior_ptid;
+ struct frame_id id;
int executing;
- /* Set INFERIOR_PTID, which is implicitly used by get_current_frame. */
- old_inferior_ptid = inferior_ptid;
- inferior_ptid = tp->ptid;
+ /* Set current thread, which is implicitly used by
+ get_current_frame. */
+ scoped_restore_current_thread restore_thread;
+
+ switch_to_thread (tp);
/* Clear the executing flag to allow changes to the current frame.
We are not actually running, yet. We just started a reverse execution
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. */
- executing = is_executing (inferior_ptid);
- set_executing (inferior_ptid, 0);
+ set EXECUTING to false. */
+ executing = tp->executing;
+ set_executing (inferior_ptid, false);
- frame = NULL;
- TRY
+ id = null_frame_id;
+ try
{
- frame = get_current_frame ();
+ 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);
- /* Restore the previous inferior_ptid. */
- inferior_ptid = old_inferior_ptid;
-
- throw_exception (except);
+ throw;
}
- END_CATCH
/* Restore the previous execution state. */
set_executing (inferior_ptid, executing);
- /* Restore the previous inferior_ptid. */
- inferior_ptid = old_inferior_ptid;
-
- return frame;
+ return id;
}
/* Start replaying a thread. */
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_info *frame;
struct frame_id frame_id;
int upd_step_frame_id, upd_step_stack_frame_id;
/* The current frame without replaying - computed via normal unwind. */
- frame = get_thread_current_frame (tp);
- frame_id = get_frame_id (frame);
+ frame_id = get_thread_current_frame_id (tp);
/* Check if we need to update any stepping-related frame id's. */
upd_step_frame_id = frame_id_eq (frame_id,
btinfo->replay = replay;
/* Make sure we're not using any stale registers. */
- registers_changed_ptid (tp->ptid);
+ registers_changed_thread (tp);
/* The current frame with replaying - computed via btrace unwind. */
- frame = get_thread_current_frame (tp);
- frame_id = get_frame_id (frame);
+ frame_id = get_thread_current_frame_id (tp);
/* Replace stepping related frames where necessary. */
if (upd_step_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_ptid (tp->ptid);
+ registers_changed_thread (tp);
- throw_exception (except);
+ throw;
}
- END_CATCH
return replay;
}
btinfo->replay = NULL;
/* Make sure we're not leaving any stale registers. */
- registers_changed_ptid (tp->ptid);
+ registers_changed_thread (tp);
}
/* Stop replaying TP if it is at the end of its execution history. */
void
record_btrace_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
{
- struct thread_info *tp;
enum btrace_thread_flag flag, cflag;
- DEBUG ("resume %s: %s%s", target_pid_to_str (ptid),
+ DEBUG ("resume %s: %s%s", target_pid_to_str (ptid).c_str (),
::execution_direction == EXEC_REVERSE ? "reverse-" : "",
step ? "step" : "cont");
if ((::execution_direction != EXEC_REVERSE)
&& !record_is_replaying (minus_one_ptid))
{
- this->beneath->resume (ptid, step, signal);
+ this->beneath ()->resume (ptid, step, signal);
return;
}
For all-stop targets, we only step INFERIOR_PTID and continue others. */
if (!target_is_non_stop_p ())
{
- gdb_assert (ptid_match (inferior_ptid, ptid));
+ gdb_assert (inferior_ptid.matches (ptid));
- ALL_NON_EXITED_THREADS (tp)
- if (ptid_match (tp->ptid, ptid))
- {
- if (ptid_match (tp->ptid, inferior_ptid))
- record_btrace_resume_thread (tp, flag);
- else
- record_btrace_resume_thread (tp, cflag);
- }
+ for (thread_info *tp : all_non_exited_threads (ptid))
+ {
+ if (tp->ptid.matches (inferior_ptid))
+ record_btrace_resume_thread (tp, flag);
+ else
+ record_btrace_resume_thread (tp, cflag);
+ }
}
else
{
- ALL_NON_EXITED_THREADS (tp)
- if (ptid_match (tp->ptid, ptid))
- record_btrace_resume_thread (tp, flag);
+ for (thread_info *tp : all_non_exited_threads (ptid))
+ record_btrace_resume_thread (tp, flag);
}
/* Async support. */
{
if ((::execution_direction != EXEC_REVERSE)
&& !record_is_replaying (minus_one_ptid))
- beneath->commit_resume ();
+ beneath ()->commit_resume ();
}
/* Cancel resuming TP. */
DEBUG ("cancel resume thread %s (%s): %x (%s)",
print_thread_id (tp),
- target_pid_to_str (tp->ptid), flags,
+ target_pid_to_str (tp->ptid).c_str (), flags,
btrace_thread_flag_to_str (flags));
tp->btrace.flags &= ~(BTHR_MOVE | BTHR_STOP);
struct btrace_insn_iterator *replay;
struct btrace_thread_info *btinfo;
const struct btrace_insn *insn;
- struct inferior *inf;
btinfo = &tp->btrace;
replay = btinfo->replay;
if (insn == NULL)
return 0;
- inf = find_inferior_ptid (tp->ptid);
- if (inf == NULL)
- return 0;
-
- return record_check_stopped_by_breakpoint (inf->aspace, insn->pc,
+ return record_check_stopped_by_breakpoint (tp->inf->aspace, insn->pc,
&btinfo->stop_reason);
}
btinfo->flags &= ~(BTHR_MOVE | BTHR_STOP);
DEBUG ("stepping thread %s (%s): %x (%s)", print_thread_id (tp),
- target_pid_to_str (tp->ptid), flags,
+ target_pid_to_str (tp->ptid).c_str (), flags,
btrace_thread_flag_to_str (flags));
/* We can't step without an execution history. */
return status;
}
-/* A vector of threads. */
-
-typedef struct thread_info * tp_t;
-DEF_VEC_P (tp_t);
-
/* Announce further events if necessary. */
static void
std::vector<thread_info *> moving;
std::vector<thread_info *> no_history;
- DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid), options);
+ DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid).c_str (), options);
/* As long as we're not replaying, just forward the request. */
if ((::execution_direction != EXEC_REVERSE)
&& !record_is_replaying (minus_one_ptid))
{
- return this->beneath->wait (ptid, status, options);
+ return this->beneath ()->wait (ptid, status, options);
}
/* Keep a work list of moving threads. */
- {
- thread_info *tp;
-
- ALL_NON_EXITED_THREADS (tp)
- {
- if (ptid_match (tp->ptid, ptid)
- && ((tp->btrace.flags & (BTHR_MOVE | BTHR_STOP)) != 0))
- moving.push_back (tp);
- }
- }
+ for (thread_info *tp : all_non_exited_threads (ptid))
+ if ((tp->btrace.flags & (BTHR_MOVE | BTHR_STOP)) != 0)
+ moving.push_back (tp);
if (moving.empty ())
{
*status = btrace_step_no_resumed ();
- DEBUG ("wait ended by %s: %s", target_pid_to_str (null_ptid),
+ DEBUG ("wait ended by %s: %s", target_pid_to_str (null_ptid).c_str (),
target_waitstatus_to_string (status).c_str ());
return null_ptid;
/* Stop all other threads. */
if (!target_is_non_stop_p ())
{
- thread_info *tp;
-
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
record_btrace_cancel_resume (tp);
}
record_btrace_clear_histories (&eventing->btrace);
/* We moved the replay position but did not update registers. */
- registers_changed_ptid (eventing->ptid);
+ registers_changed_thread (eventing);
DEBUG ("wait ended by thread %s (%s): %s",
print_thread_id (eventing),
- target_pid_to_str (eventing->ptid),
+ target_pid_to_str (eventing->ptid).c_str (),
target_waitstatus_to_string (status).c_str ());
return eventing->ptid;
void
record_btrace_target::stop (ptid_t ptid)
{
- DEBUG ("stop %s", target_pid_to_str (ptid));
+ DEBUG ("stop %s", target_pid_to_str (ptid).c_str ());
/* As long as we're not replaying, just forward the request. */
if ((::execution_direction != EXEC_REVERSE)
&& !record_is_replaying (minus_one_ptid))
{
- this->beneath->stop (ptid);
+ this->beneath ()->stop (ptid);
}
else
{
- struct thread_info *tp;
-
- ALL_NON_EXITED_THREADS (tp)
- if (ptid_match (tp->ptid, ptid))
- {
- tp->btrace.flags &= ~BTHR_MOVE;
- tp->btrace.flags |= BTHR_STOP;
- }
+ for (thread_info *tp : all_non_exited_threads (ptid))
+ {
+ tp->btrace.flags &= ~BTHR_MOVE;
+ tp->btrace.flags |= BTHR_STOP;
+ }
}
}
/* The can_execute_reverse method of target record-btrace. */
-int
+bool
record_btrace_target::can_execute_reverse ()
{
- return 1;
+ return true;
}
/* The stopped_by_sw_breakpoint method of target record-btrace. */
-int
+bool
record_btrace_target::stopped_by_sw_breakpoint ()
{
if (record_is_replaying (minus_one_ptid))
return tp->btrace.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
}
- return this->beneath->stopped_by_sw_breakpoint ();
+ return this->beneath ()->stopped_by_sw_breakpoint ();
}
/* The supports_stopped_by_sw_breakpoint method of target
record-btrace. */
-int
+bool
record_btrace_target::supports_stopped_by_sw_breakpoint ()
{
if (record_is_replaying (minus_one_ptid))
- return 1;
+ return true;
- return this->beneath->supports_stopped_by_sw_breakpoint ();
+ return this->beneath ()->supports_stopped_by_sw_breakpoint ();
}
/* The stopped_by_sw_breakpoint method of target record-btrace. */
-int
+bool
record_btrace_target::stopped_by_hw_breakpoint ()
{
if (record_is_replaying (minus_one_ptid))
return tp->btrace.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
}
- return this->beneath->stopped_by_hw_breakpoint ();
+ return this->beneath ()->stopped_by_hw_breakpoint ();
}
/* The supports_stopped_by_hw_breakpoint method of target
record-btrace. */
-int
+bool
record_btrace_target::supports_stopped_by_hw_breakpoint ()
{
if (record_is_replaying (minus_one_ptid))
- return 1;
+ return true;
- return this->beneath->supports_stopped_by_hw_breakpoint ();
+ return this->beneath ()->supports_stopped_by_hw_breakpoint ();
}
/* The update_thread_list method of target record-btrace. */
return;
/* Forward the request. */
- this->beneath->update_thread_list ();
+ this->beneath ()->update_thread_list ();
}
/* The thread_alive method of target record-btrace. */
-int
+bool
record_btrace_target::thread_alive (ptid_t ptid)
{
/* We don't add or remove threads during replay. */
if (record_is_replaying (minus_one_ptid))
- return find_thread_ptid (ptid) != NULL;
+ return true;
/* Forward the request. */
- return this->beneath->thread_alive (ptid);
+ return this->beneath ()->thread_alive (ptid);
}
/* Set the replay branch trace instruction iterator. If IT is NULL, replay
return;
*btinfo->replay = *it;
- registers_changed_ptid (tp->ptid);
+ registers_changed_thread (tp);
}
/* Start anew from the new replay position. */
record_btrace_clear_histories (btinfo);
- stop_pc = regcache_read_pc (get_current_regcache ());
+ inferior_thread ()->suspend.stop_pc
+ = regcache_read_pc (get_current_regcache ());
print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}
void
record_btrace_target::record_stop_replaying ()
{
- struct thread_info *tp;
-
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
record_btrace_stop_replaying (tp);
}
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 (exception, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
record_btrace_conf.format = BTRACE_FORMAT_NONE;
- throw_exception (exception);
+ throw;
}
- END_CATCH
}
- END_CATCH
}
/* The "set record btrace" command. */
static void
cmd_show_record_btrace_cpu (const char *args, int from_tty)
{
- const char *cpu;
-
if (args != nullptr && *args != 0)
error (_("Trailing junk: '%s'."), args);
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,
add_prefix_cmd ("cpu", class_support, cmd_set_record_btrace_cpu,
_("\
Set the cpu to be used for trace decode.\n\n\
-The format is \"<vendor>:<identifier>\" or \"none\" or \"auto\" (default).\n\
-For vendor \"intel\" the format is \"<family>/<model>[/<stepping>]\".\n\n\
+The format is \"VENDOR:IDENTIFIER\" or \"none\" or \"auto\" (default).\n\
+For vendor \"intel\" the format is \"FAMILY/MODEL[/STEPPING]\".\n\n\
When decoding branch trace, enable errata workarounds for the specified cpu.\n\
The default is \"auto\", which uses the cpu on which the trace was recorded.\n\
When GDB does not support that cpu, this option can be used to enable\n\
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);
&set_record_btrace_pt_cmdlist,
&show_record_btrace_pt_cmdlist);
- add_target (&record_btrace_ops);
+ add_target (record_btrace_target_info, record_btrace_target_open);
bfcache = htab_create_alloc (50, bfcache_hash, bfcache_eq, NULL,
xcalloc, xfree);