aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/btrace.c10
-rw-r--r--gdb/btrace.h6
-rw-r--r--gdb/record-btrace.c80
4 files changed, 100 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8239d17..d8d2961 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@
2014-01-16 Markus Metzger <markus.t.metzger@intel.com>
+ * btrace.h (replay) <replay>: New.
+ (btrace_is_replaying): New.
+ * btrace.c (btrace_clear): Free replay iterator.
+ (btrace_is_replaying): New.
+ * record-btrace.c (record_btrace_is_replaying): New.
+ (record_btrace_info): Print insn number if replaying.
+ (record_btrace_insn_history): Start at replay position.
+ (record_btrace_call_history): Start at replay position.
+ (init_record_btrace_ops): Init to_record_is_replaying.
+
+2014-01-16 Markus Metzger <markus.t.metzger@intel.com>
+
* record-btrace.c (record_btrace_insn_history_range): Include
end.
(record_btrace_insn_history_from): Adjust range.
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 1d060d3e..632ebe1 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -781,9 +781,11 @@ btrace_clear (struct thread_info *tp)
xfree (btinfo->insn_history);
xfree (btinfo->call_history);
+ xfree (btinfo->replay);
btinfo->insn_history = NULL;
btinfo->call_history = NULL;
+ btinfo->replay = NULL;
}
/* See btrace.h. */
@@ -1339,3 +1341,11 @@ btrace_set_call_history (struct btrace_thread_info *btinfo,
btinfo->call_history->begin = *begin;
btinfo->call_history->end = *end;
}
+
+/* See btrace.h. */
+
+int
+btrace_is_replaying (struct thread_info *tp)
+{
+ return tp->btrace.replay != NULL;
+}
diff --git a/gdb/btrace.h b/gdb/btrace.h
index d219f69..93e6940 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -187,6 +187,9 @@ struct btrace_thread_info
/* The function call history iterator. */
struct btrace_call_history *call_history;
+
+ /* The current replay position. NULL if not replaying. */
+ struct btrace_insn_iterator *replay;
};
/* Enable branch tracing for a thread. */
@@ -308,4 +311,7 @@ extern void btrace_set_call_history (struct btrace_thread_info *,
const struct btrace_call_iterator *begin,
const struct btrace_call_iterator *end);
+/* Determine if branch tracing is currently replaying TP. */
+extern int btrace_is_replaying (struct thread_info *tp);
+
#endif /* BTRACE_H */
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 34aee40..9a65146 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -236,6 +236,10 @@ record_btrace_info (void)
printf_unfiltered (_("Recorded %u instructions in %u functions for thread "
"%d (%s).\n"), insns, calls, tp->num,
target_pid_to_str (tp->ptid));
+
+ if (btrace_is_replaying (tp))
+ printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
+ btrace_insn_number (btinfo->replay));
}
/* Print an unsigned int. */
@@ -300,13 +304,34 @@ record_btrace_insn_history (int size, int flags)
history = btinfo->insn_history;
if (history == NULL)
{
- /* No matter the direction, we start with the tail of the trace. */
- btrace_insn_end (&begin, btinfo);
- end = begin;
+ struct btrace_insn_iterator *replay;
DEBUG ("insn-history (0x%x): %d", flags, size);
- covered = btrace_insn_prev (&begin, context);
+ /* If we're replaying, we start at the replay position. Otherwise, we
+ start at the tail of the trace. */
+ replay = btinfo->replay;
+ if (replay != NULL)
+ begin = *replay;
+ else
+ btrace_insn_end (&begin, btinfo);
+
+ /* We start from here and expand in the requested direction. Then we
+ expand in the other direction, as well, to fill up any remaining
+ context. */
+ end = begin;
+ if (size < 0)
+ {
+ /* We want the current position covered, as well. */
+ covered = btrace_insn_next (&end, 1);
+ covered += btrace_insn_prev (&begin, context - covered);
+ covered += btrace_insn_next (&end, context - covered);
+ }
+ else
+ {
+ covered = btrace_insn_next (&end, context);
+ covered += btrace_insn_prev (&begin, context - covered);
+ }
}
else
{
@@ -560,13 +585,37 @@ record_btrace_call_history (int size, int flags)
history = btinfo->call_history;
if (history == NULL)
{
- /* No matter the direction, we start with the tail of the trace. */
- btrace_call_end (&begin, btinfo);
- end = begin;
+ struct btrace_insn_iterator *replay;
DEBUG ("call-history (0x%x): %d", flags, size);
- covered = btrace_call_prev (&begin, context);
+ /* If we're replaying, we start at the replay position. Otherwise, we
+ start at the tail of the trace. */
+ replay = btinfo->replay;
+ if (replay != NULL)
+ {
+ begin.function = replay->function;
+ begin.btinfo = btinfo;
+ }
+ else
+ btrace_call_end (&begin, btinfo);
+
+ /* We start from here and expand in the requested direction. Then we
+ expand in the other direction, as well, to fill up any remaining
+ context. */
+ end = begin;
+ if (size < 0)
+ {
+ /* We want the current position covered, as well. */
+ covered = btrace_call_next (&end, 1);
+ covered += btrace_call_prev (&begin, context - covered);
+ covered += btrace_call_next (&end, context - covered);
+ }
+ else
+ {
+ covered = btrace_call_next (&end, context);
+ covered += btrace_call_prev (&begin, context- covered);
+ }
}
else
{
@@ -687,6 +736,20 @@ record_btrace_call_history_from (ULONGEST from, int size, int flags)
record_btrace_call_history_range (begin, end, flags);
}
+/* The to_record_is_replaying method of target record-btrace. */
+
+static int
+record_btrace_is_replaying (void)
+{
+ struct thread_info *tp;
+
+ ALL_THREADS (tp)
+ if (btrace_is_replaying (tp))
+ return 1;
+
+ return 0;
+}
+
/* Initialize the record-btrace target ops. */
static void
@@ -713,6 +776,7 @@ init_record_btrace_ops (void)
ops->to_call_history = record_btrace_call_history;
ops->to_call_history_from = record_btrace_call_history_from;
ops->to_call_history_range = record_btrace_call_history_range;
+ ops->to_record_is_replaying = record_btrace_is_replaying;
ops->to_stratum = record_stratum;
ops->to_magic = OPS_MAGIC;
}