public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Markus Metzger <markus.t.metzger@intel.com>
To: palves@redhat.com
Cc: gdb-patches@sourceware.org
Subject: [PATCH 2/3] btrace: allow leading trace gaps
Date: Tue, 19 Jan 2016 12:41:00 -0000	[thread overview]
Message-ID: <1453207280-21138-2-git-send-email-markus.t.metzger@intel.com> (raw)
In-Reply-To: <1453207280-21138-1-git-send-email-markus.t.metzger@intel.com>

GDB ignores trace gaps from decode errors or overflows at the beginning of the
trace.  There isn't really a gap in the trace; the trace just starts a bit
later than expected.

In cases where there is no trace at all or where the trace is smaller than
expected, this may hide the reason for the missing trace.

Allow leading trace gaps.  They will be shown as decode warnings and by the
record function-call-history command.

    (gdb) info record
    Active record target: record-btrace
    Recording format: Intel Processor Trace.
    Buffer size: 16kB.
    warning: Decode error (-6) at instruction 0 (offset = 0x58, pc = 0x0): unexpected packet context.
    warning: Decode error (-6) at instruction 0 (offset = 0xb0, pc = 0x0): unexpected packet context.
    warning: Decode error (-6) at instruction 0 (offset = 0x168, pc = 0x0): unexpected packet context.
    warning: Decode error (-6) at instruction 54205 (offset = 0xe08, pc = 0x0): unexpected packet context.
    warning: Decode error (-6) at instruction 54205 (offset = 0xe60, pc = 0x0): unexpected packet context.
    warning: Decode error (-6) at instruction 54205 (offset = 0xed8, pc = 0x0): unexpected packet context.
    Recorded 91582 instructions in 1111 functions (6 gaps) for thread 1 (process 15710).
    (gdb) record function-call-history /c 1
    1       [decode error (-6): unexpected packet context]
    2       [decode error (-6): unexpected packet context]
    3       [decode error (-6): unexpected packet context]
    4           _dl_addr
    5             ??
    6           _dl_addr
    7         ??
    8           ??
    9         ??
    10      ??

Leading trace gaps will not be shown by the record instruction-history command
without further changes.

2016-01-19  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* btrace.c (btrace_compute_ftrace_bts, ftrace_add_pt): Allow leading gaps.
	* record-btrace.c (record_btrace_single_step_forward)
	(record_btrace_single_step_backward): Jump back to last instruction if
	step ends at a gap.
	(record_btrace_goto_begin): Skip gaps.
---
 gdb/btrace.c        | 50 +++++++++++++++++++++++++-------------------------
 gdb/record-btrace.c | 33 +++++++++++++++++++++++++++------
 2 files changed, 52 insertions(+), 31 deletions(-)

diff --git a/gdb/btrace.c b/gdb/btrace.c
index af8f16a..a683bfa 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -625,17 +625,17 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 	  /* We should hit the end of the block.  Warn if we went too far.  */
 	  if (block->end < pc)
 	    {
-	      /* Indicate the gap in the trace - unless we're at the
-		 beginning.  */
-	      if (begin != NULL)
-		{
-		  end = ftrace_new_gap (end, BDE_BTS_OVERFLOW);
-		  ngaps += 1;
+	      /* Indicate the gap in the trace.  */
+	      end = ftrace_new_gap (end, BDE_BTS_OVERFLOW);
+	      if (begin == NULL)
+		begin = end;
+
+	      ngaps += 1;
+
+	      warning (_("Recorded trace may be corrupted at instruction "
+			 "%u (pc = %s)."), end->insn_offset - 1,
+		       core_addr_to_string_nz (pc));
 
-		  warning (_("Recorded trace may be corrupted at instruction "
-			     "%u (pc = %s)."), end->insn_offset - 1,
-			   core_addr_to_string_nz (pc));
-		}
 	      break;
 	    }
 
@@ -795,19 +795,22 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
 			     "= 0x%" PRIx64 ", pc = 0x%" PRIx64 ")."),
 			   end->insn_offset - 1, offset, insn.ip);
 		}
+	    }
 
-	      /* Indicate trace overflows.  */
-	      if (insn.resynced)
-		{
-		  *pend = end = ftrace_new_gap (end, BDE_PT_OVERFLOW);
-		  *ngaps += 1;
+	  /* Indicate trace overflows.  */
+	  if (insn.resynced)
+	    {
+	      *pend = end = ftrace_new_gap (end, BDE_PT_OVERFLOW);
+	      if (begin == NULL)
+		*pbegin = begin = end;
 
-		  pt_insn_get_offset (decoder, &offset);
+	      *ngaps += 1;
 
-		  warning (_("Overflow at instruction %u (offset = 0x%" PRIx64
-			     ", pc = 0x%" PRIx64 ")."), end->insn_offset - 1,
-			   offset, insn.ip);
-		}
+	      pt_insn_get_offset (decoder, &offset);
+
+	      warning (_("Overflow at instruction %u (offset = 0x%" PRIx64
+			 ", pc = 0x%" PRIx64 ")."), end->insn_offset - 1,
+		       offset, insn.ip);
 	    }
 
 	  upd = ftrace_update_function (end, insn.ip);
@@ -833,13 +836,10 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
       if (errcode == -pte_eos)
 	break;
 
-      /* If the gap is at the very beginning, we ignore it - we will have
-	 less trace, but we won't have any holes in the trace.  */
-      if (begin == NULL)
-	continue;
-
       /* Indicate the gap in the trace.  */
       *pend = end = ftrace_new_gap (end, errcode);
+      if (begin == NULL)
+	*pbegin = begin = end;
       *ngaps += 1;
 
       pt_insn_get_offset (decoder, &offset);
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 77b5180..898379d 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -2260,7 +2260,7 @@ record_btrace_replay_at_breakpoint (struct thread_info *tp)
 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;
@@ -2274,7 +2274,9 @@ record_btrace_single_step_forward (struct thread_info *tp)
   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;
@@ -2283,7 +2285,10 @@ record_btrace_single_step_forward (struct thread_info *tp)
 	 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);
 
@@ -2304,7 +2309,7 @@ record_btrace_single_step_forward (struct thread_info *tp)
 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;
@@ -2315,14 +2320,19 @@ record_btrace_single_step_backward (struct thread_info *tp)
     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);
 
@@ -2732,6 +2742,17 @@ record_btrace_goto_begin (struct target_ops *self)
   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);
 }
 
-- 
1.8.3.1

      parent reply	other threads:[~2016-01-19 12:41 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-19 12:41 [PATCH 1/3] btrace: fix gap indication Markus Metzger
2016-01-19 12:41 ` [PATCH 3/3] btrace: update tail call heuristic Markus Metzger
2016-01-19 12:41 ` Markus Metzger [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1453207280-21138-2-git-send-email-markus.t.metzger@intel.com \
    --to=markus.t.metzger@intel.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).