From: Tim Wiederhake <tim.wiederhake@intel.com>
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 [thread overview]
Message-ID: <1487337989-6367-10-git-send-email-tim.wiederhake@intel.com> (raw)
In-Reply-To: <1487337989-6367-1-git-send-email-tim.wiederhake@intel.com>
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 <tim.wiederhake@intel.com>
---
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
next prev parent reply other threads:[~2017-02-17 13:27 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-17 13:27 [PATCH 00/11] btrace: Turn linked list of function call segments into vector Tim Wiederhake
2017-02-17 13:27 ` [PATCH 02/11] btrace: Change parameters to use btrace_thread_info Tim Wiederhake
2017-02-24 9:32 ` Metzger, Markus T
2017-02-17 13:27 ` Tim Wiederhake [this message]
2017-02-17 13:27 ` [PATCH 06/11] [SQUASH] btrace: Save function calls in a vector Tim Wiederhake
2017-02-24 9:33 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 08/11] [SQUASH] btrace: Adjust struct btrace_function::{flow,segment} Tim Wiederhake
2017-02-24 9:33 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 01/11] btrace: Use struct btrace_thread_info fields directly Tim Wiederhake
2017-02-17 13:27 ` [PATCH 05/11] btrace: Use function segment index in insn iterator Tim Wiederhake
2017-02-24 9:32 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 11/11] [SQUASH] btrace: Cleanup Tim Wiederhake
2017-02-17 13:27 ` [PATCH 03/11] btrace: Add btinfo to instruction interator Tim Wiederhake
2017-02-24 9:32 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 04/11] btrace: Use function segment index in call iterator Tim Wiederhake
2017-02-24 9:32 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 10/11] [SQUASH] btrace: Remove bfun_s vector Tim Wiederhake
2017-02-17 13:27 ` [PATCH 07/11] [SQUASH] btrace: Adjust struct btrace_function::up Tim Wiederhake
2017-02-24 9:33 ` Metzger, Markus T
2017-02-24 9:32 ` [PATCH 00/11] btrace: Turn linked list of function call segments into vector Metzger, Markus T
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=1487337989-6367-10-git-send-email-tim.wiederhake@intel.com \
--to=tim.wiederhake@intel.com \
--cc=gdb-patches@sourceware.org \
--cc=markus.t.metzger@intel.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).