#include "event-loop.h"
#include "inf-loop.h"
#include "vec.h"
+#include <algorithm>
/* The target_ops of record-btrace. */
static struct target_ops record_btrace_ops;
if (sal.symtab != symtab || sal.line == 0)
continue;
- begin = min (begin, sal.line);
- end = max (end, sal.line);
+ begin = std::min (begin, sal.line);
+ end = std::max (end, sal.line);
}
out:
& SEC_READONLY) != 0)
{
/* Truncate the request to fit into this section. */
- len = min (len, section->endaddr - offset);
+ len = std::min (len, section->endaddr - offset);
break;
}
}
static int
record_btrace_remove_breakpoint (struct target_ops *ops,
struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+ struct bp_target_info *bp_tgt,
+ enum remove_bp_reason reason)
{
const char *old;
int ret;
ret = 0;
TRY
{
- ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
+ ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt,
+ reason);
}
CATCH (except, RETURN_MASK_ALL)
{
}
}
+/* The to_commit_resume method of target record-btrace. */
+
+static void
+record_btrace_commit_resume (struct target_ops *ops)
+{
+ if ((execution_direction != EXEC_REVERSE)
+ && !record_btrace_is_replaying (ops, minus_one_ptid))
+ ops->beneath->to_commit_resume (ops->beneath);
+}
+
/* Cancel resuming TP. */
static void
static struct target_waitstatus
record_btrace_single_step_forward (struct thread_info *tp)
{
- struct btrace_insn_iterator *replay, end;
+ struct btrace_insn_iterator *replay, end, start;
struct btrace_thread_info *btinfo;
btinfo = &tp->btrace;
if (record_btrace_replay_at_breakpoint (tp))
return btrace_step_stopped ();
- /* Skip gaps during replay. */
+ /* Skip gaps during replay. If we end up at a gap (at the end of the trace),
+ jump back to the instruction at which we started. */
+ start = *replay;
do
{
unsigned int steps;
of the execution history. */
steps = btrace_insn_next (replay, 1);
if (steps == 0)
- return btrace_step_no_history ();
+ {
+ *replay = start;
+ return btrace_step_no_history ();
+ }
}
while (btrace_insn_get (replay) == NULL);
static struct target_waitstatus
record_btrace_single_step_backward (struct thread_info *tp)
{
- struct btrace_insn_iterator *replay;
+ struct btrace_insn_iterator *replay, start;
struct btrace_thread_info *btinfo;
btinfo = &tp->btrace;
replay = record_btrace_start_replaying (tp);
/* If we can't step any further, we reached the end of the history.
- Skip gaps during replay. */
+ Skip gaps during replay. If we end up at a gap (at the beginning of
+ the trace), jump back to the instruction at which we started. */
+ start = *replay;
do
{
unsigned int steps;
steps = btrace_insn_prev (replay, 1);
if (steps == 0)
- return btrace_step_no_history ();
+ {
+ *replay = start;
+ return btrace_step_no_history ();
+ }
}
while (btrace_insn_get (replay) == NULL);
tp = require_btrace_thread ();
btrace_insn_begin (&begin, &tp->btrace);
+
+ /* Skip gaps at the beginning of the trace. */
+ while (btrace_insn_get (&begin) == NULL)
+ {
+ unsigned int steps;
+
+ steps = btrace_insn_next (&begin, 1);
+ if (steps == 0)
+ error (_("No trace."));
+ }
+
record_btrace_set_replay (tp, &begin);
}
ops->to_get_unwinder = &record_btrace_to_get_unwinder;
ops->to_get_tailcall_unwinder = &record_btrace_to_get_tailcall_unwinder;
ops->to_resume = record_btrace_resume;
+ ops->to_commit_resume = record_btrace_commit_resume;
ops->to_wait = record_btrace_wait;
ops->to_stop = record_btrace_stop;
ops->to_update_thread_list = record_btrace_update_thread_list;