From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2008 invoked by alias); 13 Feb 2017 12:38:14 -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 1961 invoked by uid 89); 13 Feb 2017 12:38:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.3 required=5.0 tests=AWL,BAYES_50,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=timwiederhakeintelcom, tim.wiederhake@intel.com, sk:btrace_, btrace.h X-HELO: mga04.intel.com Received: from mga04.intel.com (HELO mga04.intel.com) (192.55.52.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 13 Feb 2017 12:38:11 +0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Feb 2017 04:38:10 -0800 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga002.fm.intel.com with ESMTP; 13 Feb 2017 04:38:08 -0800 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 v1DCc8Bj010224; Mon, 13 Feb 2017 12:38:08 GMT Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id v1DCc8M6011579; Mon, 13 Feb 2017 13:38:08 +0100 Received: (from twiederh@localhost) by ulvlx001.iul.intel.com with œ id v1DCc7mI011575; Mon, 13 Feb 2017 13:38:08 +0100 From: Tim Wiederhake To: gdb-patches@sourceware.org Cc: markus.t.metzger@intel.com, palves@redhat.com, xdje42@gmail.com Subject: [PATCH v6 1/9] btrace: Count gaps as one instruction explicitly. Date: Mon, 13 Feb 2017 12:38:00 -0000 Message-Id: <1486989450-11313-2-git-send-email-tim.wiederhake@intel.com> In-Reply-To: <1486989450-11313-1-git-send-email-tim.wiederhake@intel.com> References: <1486989450-11313-1-git-send-email-tim.wiederhake@intel.com> X-IsSubscribed: yes X-SW-Source: 2017-02/txt/msg00327.txt.bz2 This gives all instructions, including gaps, a unique number. Add a function to retrieve the error code if a btrace instruction iterator points to an invalid instruction. 2017-02-13 Tim Wiederhake gdb/ChangeLog: * btrace.c (ftrace_call_num_insn, btrace_insn_get_error): New function. (ftrace_new_function, btrace_insn_number, btrace_insn_cmp, btrace_find_insn_by_number): Remove special case for gaps. * btrace.h (btrace_insn_get_error): New export. (btrace_insn_number, btrace_find_insn_by_number): Adjust comment. * record-btrace.c (btrace_insn_history): Print number for gaps. (record_btrace_info, record_btrace_goto): Handle gaps. --- gdb/btrace.c | 84 ++++++++++++++++++----------------------------------- gdb/btrace.h | 9 ++++-- gdb/record-btrace.c | 34 ++++++++-------------- 3 files changed, 46 insertions(+), 81 deletions(-) diff --git a/gdb/btrace.c b/gdb/btrace.c index 6d621e4..3704d9a 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -141,6 +141,21 @@ ftrace_debug (const struct btrace_function *bfun, const char *prefix) prefix, fun, file, level, ibegin, iend); } +/* Return the number of instructions in a given function call segment. */ + +static unsigned int +ftrace_call_num_insn (const struct btrace_function* bfun) +{ + if (bfun == NULL) + return 0; + + /* A gap is always counted as one instruction. */ + if (bfun->errcode != 0) + return 1; + + return VEC_length (btrace_insn_s, bfun->insn); +} + /* Return non-zero if BFUN does not match MFUN and FUN, return zero otherwise. */ @@ -216,8 +231,7 @@ ftrace_new_function (struct btrace_function *prev, prev->flow.next = bfun; bfun->number = prev->number + 1; - bfun->insn_offset = (prev->insn_offset - + VEC_length (btrace_insn_s, prev->insn)); + bfun->insn_offset = prev->insn_offset + ftrace_call_num_insn (prev); bfun->level = prev->level; } @@ -2176,18 +2190,18 @@ btrace_insn_get (const struct btrace_insn_iterator *it) /* See btrace.h. */ -unsigned int -btrace_insn_number (const struct btrace_insn_iterator *it) +int +btrace_insn_get_error (const struct btrace_insn_iterator *it) { - const struct btrace_function *bfun; - - bfun = it->function; + return it->function->errcode; +} - /* Return zero if the iterator points to a gap in the trace. */ - if (bfun->errcode != 0) - return 0; +/* See btrace.h. */ - return bfun->insn_offset + it->index; +unsigned int +btrace_insn_number (const struct btrace_insn_iterator *it) +{ + return it->function->insn_offset + it->index; } /* See btrace.h. */ @@ -2382,37 +2396,6 @@ btrace_insn_cmp (const struct btrace_insn_iterator *lhs, lnum = btrace_insn_number (lhs); rnum = btrace_insn_number (rhs); - /* A gap has an instruction number of zero. Things are getting more - complicated if gaps are involved. - - We take the instruction number offset from the iterator's function. - This is the number of the first instruction after the gap. - - This is OK as long as both lhs and rhs point to gaps. If only one of - them does, we need to adjust the number based on the other's regular - instruction number. Otherwise, a gap might compare equal to an - instruction. */ - - if (lnum == 0 && rnum == 0) - { - lnum = lhs->function->insn_offset; - rnum = rhs->function->insn_offset; - } - else if (lnum == 0) - { - lnum = lhs->function->insn_offset; - - if (lnum == rnum) - lnum -= 1; - } - else if (rnum == 0) - { - rnum = rhs->function->insn_offset; - - if (rnum == lnum) - rnum -= 1; - } - return (int) (lnum - rnum); } @@ -2424,26 +2407,15 @@ btrace_find_insn_by_number (struct btrace_insn_iterator *it, unsigned int number) { const struct btrace_function *bfun; - unsigned int end, length; for (bfun = btinfo->end; bfun != NULL; bfun = bfun->flow.prev) - { - /* Skip gaps. */ - if (bfun->errcode != 0) - continue; - - if (bfun->insn_offset <= number) - break; - } + if (bfun->insn_offset <= number) + break; if (bfun == NULL) return 0; - length = VEC_length (btrace_insn_s, bfun->insn); - gdb_assert (length > 0); - - end = bfun->insn_offset + length; - if (end <= number) + if (bfun->insn_offset + ftrace_call_num_insn (bfun) <= number) return 0; it->function = bfun; diff --git a/gdb/btrace.h b/gdb/btrace.h index dcc776a..f9af46c 100644 --- a/gdb/btrace.h +++ b/gdb/btrace.h @@ -405,9 +405,12 @@ extern void parse_xml_btrace_conf (struct btrace_config *conf, const char *xml); extern const struct btrace_insn * btrace_insn_get (const struct btrace_insn_iterator *); +/* Return the error code for a branch trace instruction iterator. Returns zero + if there is no error, i.e. the instruction is valid. */ +extern int btrace_insn_get_error (const struct btrace_insn_iterator *); + /* Return the instruction number for a branch trace iterator. - Returns one past the maximum instruction number for the end iterator. - Returns zero if the iterator does not point to a valid instruction. */ + Returns one past the maximum instruction number for the end iterator. */ extern unsigned int btrace_insn_number (const struct btrace_insn_iterator *); /* Initialize a branch trace instruction iterator to point to the begin/end of @@ -433,7 +436,7 @@ extern unsigned int btrace_insn_prev (struct btrace_insn_iterator *, extern int btrace_insn_cmp (const struct btrace_insn_iterator *lhs, const struct btrace_insn_iterator *rhs); -/* Find an instruction in the function branch trace by its number. +/* Find an instruction or gap in the function branch trace by its number. If the instruction is found, initialize the branch trace instruction iterator to point to this instruction and return non-zero. Return zero otherwise. */ diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index daa0696..1dbf5d8 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -443,28 +443,12 @@ record_btrace_info (struct target_ops *self) calls = btrace_call_number (&call); btrace_insn_end (&insn, btinfo); - insns = btrace_insn_number (&insn); - if (insns != 0) - { - /* The last instruction does not really belong to the trace. */ - insns -= 1; - } - else - { - unsigned int steps; - /* Skip gaps at the end. */ - do - { - steps = btrace_insn_prev (&insn, 1); - if (steps == 0) - break; - - insns = btrace_insn_number (&insn); - } - while (insns == 0); - } + /* If the last instruction is not a gap, it is the current instruction + that is not actually part of the record. */ + if (btrace_insn_get (&insn) != NULL) + insns -= 1; gaps = btinfo->ngaps; } @@ -737,7 +721,11 @@ btrace_insn_history (struct ui_out *uiout, /* We have trace so we must have a configuration. */ gdb_assert (conf != NULL); - btrace_ui_out_decode_error (uiout, it.function->errcode, + uiout->field_fmt ("insn-number", "%u", + btrace_insn_number (&it)); + uiout->text ("\t"); + + btrace_ui_out_decode_error (uiout, btrace_insn_get_error (&it), conf->format); } else @@ -2828,7 +2816,9 @@ record_btrace_goto (struct target_ops *self, ULONGEST insn) tp = require_btrace_thread (); found = btrace_find_insn_by_number (&it, &tp->btrace, number); - if (found == 0) + + /* Check if the instruction could not be found or is a gap. */ + if (found == 0 || btrace_insn_get (&it) == NULL) error (_("No such instruction.")); record_btrace_set_replay (tp, &it); -- 2.7.4