From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 66349 invoked by alias); 22 Jul 2016 08:12:17 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 66330 invoked by uid 89); 22 Jul 2016 08:12:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=Recording, Indicate, (unknown), upd X-HELO: mga03.intel.com Received: from mga03.intel.com (HELO mga03.intel.com) (134.134.136.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 22 Jul 2016 08:12:05 +0000 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP; 22 Jul 2016 01:12:04 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by FMSMGA003.fm.intel.com with ESMTP; 22 Jul 2016 01:12:02 -0700 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id u6M8C1J8019882; Fri, 22 Jul 2016 09:12:01 +0100 Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id u6M8C1Bc019942; Fri, 22 Jul 2016 10:12:01 +0200 Received: (from mmetzger@localhost) by ulvlx001.iul.intel.com with œ id u6M8C1up019938; Fri, 22 Jul 2016 10:12:01 +0200 From: Markus Metzger To: gdb-patches@sourceware.org Cc: palves@redhat.com Subject: [PATCH 2/5] btrace: allow leading trace gaps Date: Fri, 22 Jul 2016 08:12:00 -0000 Message-Id: <1469175120-19657-3-git-send-email-markus.t.metzger@intel.com> In-Reply-To: <1469175120-19657-1-git-send-email-markus.t.metzger@intel.com> References: <1469175120-19657-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes X-SW-Source: 2016-07/txt/msg00275.txt.bz2 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-07-22 Markus Metzger 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 5376cfa..e0d0f27 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 24594a9..b3318cd 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -2262,7 +2262,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; @@ -2276,7 +2276,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; @@ -2285,7 +2287,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); @@ -2306,7 +2311,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; @@ -2317,14 +2322,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); @@ -2734,6 +2744,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