From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2071 invoked by alias); 17 Feb 2017 13:27:31 -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 1954 invoked by uid 89); 17 Feb 2017 13:27:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.8 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=5318 X-HELO: mga02.intel.com Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 Feb 2017 13:27:19 +0000 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Feb 2017 05:27:12 -0800 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga001.fm.intel.com with ESMTP; 17 Feb 2017 05:27:11 -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 v1HDRAak001630; Fri, 17 Feb 2017 13:27:10 GMT Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id v1HDRANB006687; Fri, 17 Feb 2017 14:27:10 +0100 Received: (from twiederh@localhost) by ulvlx001.iul.intel.com with œ id v1HDRA58006683; Fri, 17 Feb 2017 14:27:10 +0100 From: Tim Wiederhake To: gdb-patches@sourceware.org Cc: markus.t.metzger@intel.com Subject: [PATCH 09/11] [SQUASH] btrace: Remove struct btrace_thread_info::{begin,end}. Date: Fri, 17 Feb 2017 13:27:00 -0000 Message-Id: <1487337989-6367-10-git-send-email-tim.wiederhake@intel.com> In-Reply-To: <1487337989-6367-1-git-send-email-tim.wiederhake@intel.com> References: <1487337989-6367-1-git-send-email-tim.wiederhake@intel.com> X-IsSubscribed: yes X-SW-Source: 2017-02/txt/msg00492.txt.bz2 This patch stands alone for easier review and is meant to be squashed together for committing. ChangeLog will be added to the squashed commit. 2017-02-17 Tim Wiederhake --- gdb/btrace.c | 159 +++++++++++++++++++++++++--------------------------- gdb/btrace.h | 1 - gdb/record-btrace.c | 2 +- 3 files changed, 77 insertions(+), 85 deletions(-) diff --git a/gdb/btrace.c b/gdb/btrace.c index 701daa3..cd2475d 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -402,8 +402,8 @@ ftrace_new_return (struct btrace_thread_info *btinfo, { struct btrace_function *prev, *bfun, *caller; - prev = btinfo->end; bfun = ftrace_new_function (btinfo, mfun, fun); + prev = ftrace_find_call_by_number (btinfo, bfun->number - 1); /* It is important to start at PREV's caller. Otherwise, we might find PREV itself, if PREV is a recursive function. */ @@ -500,16 +500,17 @@ ftrace_new_switch (struct btrace_thread_info *btinfo, static struct btrace_function * ftrace_new_gap (struct btrace_thread_info *btinfo, int errcode) { - struct btrace_function *prev, *bfun; - - prev = btinfo->end; + struct btrace_function *bfun; - /* We hijack prev if it was empty. */ - if (prev != NULL && prev->errcode == 0 - && VEC_empty (btrace_insn_s, prev->insn)) - bfun = prev; - else + if (VEC_empty (btrace_fun_s, btinfo->functions)) bfun = ftrace_new_function (btinfo, NULL, NULL); + else + { + /* We hijack the previous function call segment if it was empty. */ + bfun = VEC_last (btrace_fun_s, btinfo->functions); + if (bfun->errcode != 0 || !VEC_empty (btrace_insn_s, bfun->insn)) + bfun = ftrace_new_function (btinfo, NULL, NULL); + } bfun->errcode = errcode; @@ -531,8 +532,6 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc) struct btrace_insn *last; struct btrace_function *bfun; - bfun = btinfo->end; - /* Try to determine the function we're in. We use both types of symbols to avoid surprises when we sometimes get a full symbol and sometimes only a minimal symbol. */ @@ -543,8 +542,13 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc) if (fun == NULL && mfun == NULL) DEBUG_FTRACE ("no symbol at %s", core_addr_to_string_nz (pc)); - /* If we didn't have a function or if we had a gap before, we create one. */ - if (bfun == NULL || bfun->errcode != 0) + /* If we didn't have a function, we create one. */ + if (VEC_empty (btrace_fun_s, btinfo->functions)) + return ftrace_new_function (btinfo, mfun, fun); + + /* If we had a gap before, we create a function. */ + bfun = VEC_last (btrace_fun_s, btinfo->functions); + if (bfun->errcode != 0) return ftrace_new_function (btinfo, mfun, fun); /* Check the last instruction, if we have one. @@ -627,7 +631,7 @@ static void ftrace_update_insns (struct btrace_thread_info *btinfo, const struct btrace_insn *insn) { - struct btrace_function *bfun = btinfo->end; + struct btrace_function *bfun = VEC_last (btrace_fun_s, btinfo->functions); VEC_safe_push (btrace_insn_s, bfun->insn, insn); @@ -708,28 +712,26 @@ ftrace_fixup_level (struct btrace_thread_info *btinfo, static void ftrace_compute_global_level_offset (struct btrace_thread_info *btinfo) { - struct btrace_function *bfun, *end; - int level; + struct btrace_function *bfun; + int i, length, level; if (btinfo == NULL) return; - bfun = btinfo->begin; - if (bfun == NULL) + if (VEC_empty (btrace_fun_s, btinfo->functions)) return; - /* The last function segment contains the current instruction, which is not - really part of the trace. If it contains just this one instruction, we - stop when we reach it; otherwise, we let the below loop run to the end. */ - end = btinfo->end; - if (VEC_length (btrace_insn_s, end->insn) > 1) - end = NULL; - level = INT_MAX; - while (bfun != end) + length = VEC_length (btrace_fun_s, btinfo->functions); + for (i = 0; VEC_iterate (btrace_fun_s, btinfo->functions, i, bfun); i++) { + /* The last function segment contains the current instruction, which is + not really part of the trace. If it contains just this one + instruction, we ignore the segment. */ + if (bfun->number == length && VEC_length (btrace_insn_s, bfun->insn) == 1) + continue; + level = std::min (level, bfun->level); - bfun = ftrace_find_call_by_number (btinfo, bfun->number + 1); } DEBUG_FTRACE ("setting global level offset: %d", -level); @@ -1033,9 +1035,13 @@ btrace_compute_ftrace_bts (struct thread_info *tp, gdbarch = target_gdbarch (); btinfo = &tp->btrace; - level = btinfo->begin != NULL ? -btinfo->level : INT_MAX; blk = VEC_length (btrace_block_s, btrace->blocks); + if (VEC_empty (btrace_fun_s, btinfo->functions)) + level = INT_MAX; + else + level = -btinfo->level; + while (blk != 0) { btrace_block_s *block; @@ -1048,6 +1054,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp, for (;;) { + struct btrace_function *bfun; struct btrace_insn insn; int size; @@ -1055,27 +1062,23 @@ btrace_compute_ftrace_bts (struct thread_info *tp, if (block->end < pc) { /* Indicate the gap in the trace. */ - btinfo->end = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW); - if (btinfo->begin == NULL) - btinfo->begin = btinfo->end; + bfun = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW); - VEC_safe_push (bfun_s, *gaps, btinfo->end); + VEC_safe_push (bfun_s, *gaps, bfun); warning (_("Recorded trace may be corrupted at instruction " - "%u (pc = %s)."), btinfo->end->insn_offset - 1, + "%u (pc = %s)."), bfun->insn_offset - 1, core_addr_to_string_nz (pc)); break; } - btinfo->end = ftrace_update_function (btinfo, pc); - if (btinfo->begin == NULL) - btinfo->begin = btinfo->end; + bfun = ftrace_update_function (btinfo, pc); /* Maintain the function level offset. For all but the last block, we do it here. */ if (blk != 0) - level = std::min (level, btinfo->end->level); + level = std::min (level, bfun->level); size = 0; TRY @@ -1103,12 +1106,12 @@ btrace_compute_ftrace_bts (struct thread_info *tp, { /* Indicate the gap in the trace. We just added INSN so we're not at the beginning. */ - btinfo->end = ftrace_new_gap (btinfo, BDE_BTS_INSN_SIZE); + bfun = ftrace_new_gap (btinfo, BDE_BTS_INSN_SIZE); - VEC_safe_push (bfun_s, *gaps, btinfo->end); + VEC_safe_push (bfun_s, *gaps, bfun); warning (_("Recorded trace may be incomplete at instruction %u " - "(pc = %s)."), btinfo->end->insn_offset - 1, + "(pc = %s)."), bfun->insn_offset - 1, core_addr_to_string_nz (pc)); break; @@ -1123,7 +1126,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp, and is not really part of the execution history, it shouldn't affect the level. */ if (blk == 0) - level = std::min (level, btinfo->end->level); + level = std::min (level, bfun->level); } } @@ -1174,7 +1177,7 @@ ftrace_add_pt (struct pt_insn_decoder *decoder, struct btrace_thread_info *btinfo, int *plevel, VEC (bfun_s) **gaps) { - struct btrace_function *upd; + struct btrace_function *bfun, *upd; uint64_t offset; int errcode; @@ -1200,7 +1203,7 @@ ftrace_add_pt (struct pt_insn_decoder *decoder, break; /* Look for gaps in the trace - unless we're at the beginning. */ - if (btinfo->begin != NULL) + if (!VEC_empty (btrace_fun_s, btinfo->functions)) { /* Tracing is disabled and re-enabled each time we enter the kernel. Most times, we continue from the same instruction we @@ -1209,45 +1212,36 @@ ftrace_add_pt (struct pt_insn_decoder *decoder, from some other instruction. Indicate this as a trace gap. */ if (insn.enabled) { - btinfo->end = ftrace_new_gap (btinfo, BDE_PT_DISABLED); + bfun = ftrace_new_gap (btinfo, BDE_PT_DISABLED); - VEC_safe_push (bfun_s, *gaps, btinfo->end); + VEC_safe_push (bfun_s, *gaps, bfun); pt_insn_get_offset (decoder, &offset); warning (_("Non-contiguous trace at instruction %u (offset " "= 0x%" PRIx64 ", pc = 0x%" PRIx64 ")."), - btinfo->end->insn_offset - 1, offset, insn.ip); + bfun->insn_offset - 1, offset, insn.ip); } } /* Indicate trace overflows. */ if (insn.resynced) { - btinfo->end = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW); - if (btinfo->begin == NULL) - btinfo->begin = btinfo->end; + bfun = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW); - VEC_safe_push (bfun_s, *gaps, btinfo->end); + VEC_safe_push (bfun_s, *gaps, bfun); pt_insn_get_offset (decoder, &offset); warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ", pc = 0x%" PRIx64 ")."), - btinfo->end->insn_offset - 1, offset, insn.ip); + bfun->insn_offset - 1, offset, insn.ip); } - upd = ftrace_update_function (btinfo, insn.ip); - if (upd != btinfo->end) - { - btinfo->end = upd; - - if (btinfo->begin == NULL) - btinfo->begin = upd; - } + bfun = ftrace_update_function (btinfo, insn.ip); /* Maintain the function level offset. */ - *plevel = std::min (*plevel, btinfo->end->level); + *plevel = std::min (*plevel, bfun->level); btinsn.pc = (CORE_ADDR) insn.ip; btinsn.size = (gdb_byte) insn.size; @@ -1261,17 +1255,15 @@ ftrace_add_pt (struct pt_insn_decoder *decoder, break; /* Indicate the gap in the trace. */ - btinfo->end = ftrace_new_gap (btinfo, errcode); - if (btinfo->begin == NULL) - btinfo->begin = btinfo->end; + bfun = ftrace_new_gap (btinfo, errcode); - VEC_safe_push (bfun_s, *gaps, btinfo->end); + VEC_safe_push (bfun_s, *gaps, bfun); pt_insn_get_offset (decoder, &offset); warning (_("Decode error (%d) at instruction %u (offset = 0x%" PRIx64 ", pc = 0x%" PRIx64 "): %s."), errcode, - btinfo->end->insn_offset - 1, offset, insn.ip, + bfun->insn_offset - 1, offset, insn.ip, pt_errstr (pt_errcode (errcode))); } } @@ -1353,7 +1345,10 @@ btrace_compute_ftrace_pt (struct thread_info *tp, return; btinfo = &tp->btrace; - level = btinfo->begin != NULL ? -btinfo->level : INT_MAX; + if (VEC_empty (btrace_fun_s, btinfo->functions)) + level = INT_MAX; + else + level = -btinfo->level; pt_config_init(&config); config.begin = btrace->data; @@ -1391,11 +1386,14 @@ btrace_compute_ftrace_pt (struct thread_info *tp, CATCH (error, RETURN_MASK_ALL) { /* Indicate a gap in the trace if we quit trace processing. */ - if (error.reason == RETURN_QUIT && btinfo->end != NULL) + if (error.reason == RETURN_QUIT && !VEC_empty (btrace_fun_s, + btinfo->functions)) { - btinfo->end = ftrace_new_gap (btinfo, BDE_PT_USER_QUIT); + struct btrace_function *bfun; + + bfun = ftrace_new_gap (btinfo, BDE_PT_USER_QUIT); - VEC_safe_push (bfun_s, *gaps, btinfo->end); + VEC_safe_push (bfun_s, *gaps, bfun); } btrace_finalize_ftrace_pt (decoder, tp, level); @@ -1627,8 +1625,9 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp) btrace_block_s *first_new_block; btinfo = &tp->btrace; - last_bfun = btinfo->end; - gdb_assert (last_bfun != NULL); + gdb_assert (!VEC_empty (btrace_fun_s, btinfo->functions)); + + last_bfun = VEC_last (btrace_fun_s, btinfo->functions); gdb_assert (!VEC_empty (btrace_block_s, btrace->blocks)); /* If the existing trace ends with a gap, we just glue the traces @@ -1695,7 +1694,7 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp) of just that one instruction. If we remove it, we might turn the now empty btrace function segment into a gap. But we don't want gaps at the beginning. To avoid this, we remove the entire old trace. */ - if (last_bfun == btinfo->begin && VEC_empty (btrace_insn_s, last_bfun->insn)) + if (last_bfun->number == 1 && VEC_empty (btrace_insn_s, last_bfun->insn)) btrace_clear (tp); return 0; @@ -1857,7 +1856,7 @@ btrace_fetch (struct thread_info *tp) cleanup = make_cleanup_btrace_data (&btrace); /* Let's first try to extend the trace we already have. */ - if (btinfo->end != NULL) + if (!VEC_empty (btrace_fun_s, btinfo->functions)) { errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_DELTA); if (errcode == 0) @@ -1933,9 +1932,6 @@ btrace_clear (struct thread_info *tp) } VEC_truncate (btrace_fun_s, btinfo->functions, 0); - - btinfo->begin = NULL; - btinfo->end = NULL; btinfo->ngaps = 0; /* Must clear the maint data before - it depends on BTINFO->DATA. */ @@ -2324,10 +2320,7 @@ void btrace_insn_begin (struct btrace_insn_iterator *it, const struct btrace_thread_info *btinfo) { - const struct btrace_function *bfun; - - bfun = btinfo->begin; - if (bfun == NULL) + if (VEC_empty (btrace_fun_s, btinfo->functions)) error (_("No trace.")); it->btinfo = btinfo; @@ -2344,10 +2337,10 @@ btrace_insn_end (struct btrace_insn_iterator *it, const struct btrace_function *bfun; unsigned int length; - bfun = btinfo->end; - if (bfun == NULL) + if (VEC_empty (btrace_fun_s, btinfo->functions)) error (_("No trace.")); + bfun = VEC_last (btrace_fun_s, btinfo->functions); length = VEC_length (btrace_insn_s, bfun->insn); /* The last function may either be a gap or it contains the current @@ -2780,7 +2773,7 @@ btrace_is_empty (struct thread_info *tp) btinfo = &tp->btrace; - if (btinfo->begin == NULL) + if (VEC_empty (btrace_fun_s, btinfo->functions)) return 1; btrace_insn_begin (&begin, btinfo); diff --git a/gdb/btrace.h b/gdb/btrace.h index 8f8a7fa..d238d4f 100644 --- a/gdb/btrace.h +++ b/gdb/btrace.h @@ -335,7 +335,6 @@ struct btrace_thread_info part of the execution history. Both will be NULL if there is no branch trace available. If there is branch trace available, both will be non-NULL. */ - struct btrace_function *begin; struct btrace_function *end; /* Vector of decoded function call segments in execution flow order. Note diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 7ba3844..160424e 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -1928,7 +1928,7 @@ record_btrace_start_replaying (struct thread_info *tp) replay = NULL; /* We can't start replaying without trace. */ - if (btinfo->begin == NULL) + if (VEC_empty (btrace_fun_s, btinfo->functions)) return NULL; /* GDB stores the current frame_id when stepping in order to detects steps -- 2.7.4