This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v2 11/11] btrace: Store function segments as objects.
- From: Tim Wiederhake <tim dot wiederhake at intel dot com>
- To: gdb-patches at sourceware dot org
- Cc: markus dot t dot metzger at intel dot com
- Date: Mon, 8 May 2017 10:13:05 +0200
- Subject: [PATCH v2 11/11] btrace: Store function segments as objects.
- Authentication-results: sourceware.org; auth=none
- References: <1494231185-4709-1-git-send-email-tim.wiederhake@intel.com>
2017-05-08 Tim Wiederhake <tim.wiederhake@intel.com>
gdb/ChangeLog:
* btrace.c (ftrace_new_function): Adjust for renamed typedef. Store new
function segment as object.
(btrace_clear): Adjust for renamed typedef. Adjust for vector of
objects instead of vector of pointers.
(ftrace_find_call_by_number, ftrace_new_call, ftrace_new_tailcall,
ftrace_new_return, ftrace_new_switch, ftrace_new_gap,
ftrace_update_function, ftrace_compute_global_level_offset,
btrace_compute_ftrace_bts, ftrace_add_pt, btrace_compute_ftrace_pt,
btrace_stitch_bts, btrace_fetch, btrace_insn_get,
btrace_insn_get_error, btrace_insn_number, btrace_insn_begin,
btrace_insn_end, btrace_insn_next, btrace_insn_prev,
btrace_find_insn_by_number, btrace_ends_with_single_insn,
btrace_call_get, btrace_call_number, btrace_call_begin,
btrace_call_end, btrace_call_next, btrace_call_prev,
btrace_find_call_by_number, btrace_is_empty): Adjust for renamed
typedef.
* btrace.h: Replace typedef and vector defines from vector of pointers
to vector of objects.
(struct btrace_thread_info) <functions>: Change from vector of pointers
to vector of objects.
* record-btrace.c (record_btrace_frame_this_id,
record_btrace_frame_prev_register, record_btrace_frame_sniffer,
record_btrace_tailcall_frame_sniffer, record_btrace_start_replaying):
Adjust for renamed typedef.
---
gdb/btrace.c | 127 ++++++++++++++++++++++++----------------------------
gdb/btrace.h | 12 ++---
gdb/record-btrace.c | 12 ++---
3 files changed, 72 insertions(+), 79 deletions(-)
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 28afa2b..6759ccd 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -160,10 +160,10 @@ static struct btrace_function *
ftrace_find_call_by_number (const struct btrace_thread_info *btinfo,
unsigned int number)
{
- if (number == 0 || number > VEC_length (btrace_fun_p, btinfo->functions))
+ if (number == 0 || number > VEC_length (btrace_fun_s, btinfo->functions))
return NULL;
- return VEC_index (btrace_fun_p, btinfo->functions, number - 1);
+ return VEC_index (btrace_fun_s, btinfo->functions, number - 1);
}
/* Return non-zero if BFUN does not match MFUN and FUN,
@@ -222,30 +222,24 @@ ftrace_new_function (struct btrace_thread_info *btinfo,
struct minimal_symbol *mfun,
struct symbol *fun)
{
- struct btrace_function *bfun;
-
- bfun = XCNEW (struct btrace_function);
+ struct btrace_function bfun {mfun, fun, 0, 0, 0, NULL, 0, 0, 0, 0, 0};
- bfun->msym = mfun;
- bfun->sym = fun;
-
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
{
/* Start counting at one. */
- bfun->number = 1;
- bfun->insn_offset = 1;
+ bfun.number = 1;
+ bfun.insn_offset = 1;
}
else
{
- struct btrace_function *prev = VEC_last (btrace_fun_p, btinfo->functions);
+ struct btrace_function *prev = VEC_last (btrace_fun_s, btinfo->functions);
- bfun->number = prev->number + 1;
- bfun->insn_offset = prev->insn_offset + ftrace_call_num_insn (prev);
- bfun->level = prev->level;
+ bfun.number = prev->number + 1;
+ bfun.insn_offset = prev->insn_offset + ftrace_call_num_insn (prev);
+ bfun.level = prev->level;
}
- VEC_safe_push (btrace_fun_p, btinfo->functions, bfun);
- return bfun;
+ return VEC_safe_push (btrace_fun_s, btinfo->functions, &bfun);
}
/* Update the UP field of a function segment. */
@@ -302,7 +296,7 @@ ftrace_new_call (struct btrace_thread_info *btinfo,
struct minimal_symbol *mfun,
struct symbol *fun)
{
- const unsigned int length = VEC_length (btrace_fun_p, btinfo->functions);
+ const unsigned int length = VEC_length (btrace_fun_s, btinfo->functions);
struct btrace_function *bfun = ftrace_new_function (btinfo, mfun, fun);
bfun->up = length;
@@ -322,7 +316,7 @@ ftrace_new_tailcall (struct btrace_thread_info *btinfo,
struct minimal_symbol *mfun,
struct symbol *fun)
{
- const unsigned int length = VEC_length (btrace_fun_p, btinfo->functions);
+ const unsigned int length = VEC_length (btrace_fun_s, btinfo->functions);
struct btrace_function *bfun = ftrace_new_function (btinfo, mfun, fun);
bfun->up = length;
@@ -407,10 +401,10 @@ ftrace_new_return (struct btrace_thread_info *btinfo,
struct minimal_symbol *mfun,
struct symbol *fun)
{
- struct btrace_function *prev = VEC_last (btrace_fun_p, btinfo->functions);
- struct btrace_function *bfun, *caller;
+ struct btrace_function *prev, *bfun, *caller;
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. */
@@ -489,12 +483,12 @@ ftrace_new_switch (struct btrace_thread_info *btinfo,
struct minimal_symbol *mfun,
struct symbol *fun)
{
- struct btrace_function *prev = VEC_last (btrace_fun_p, btinfo->functions);
- struct btrace_function *bfun;
+ struct btrace_function *prev, *bfun;
/* This is an unexplained function switch. We can't really be sure about the
call stack, yet the best I can think of right now is to preserve it. */
bfun = ftrace_new_function (btinfo, mfun, fun);
+ prev = ftrace_find_call_by_number (btinfo, bfun->number - 1);
bfun->up = prev->up;
bfun->flags = prev->flags;
@@ -514,12 +508,12 @@ ftrace_new_gap (struct btrace_thread_info *btinfo, int errcode,
{
struct btrace_function *bfun;
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
bfun = ftrace_new_function (btinfo, NULL, NULL);
else
{
/* We hijack the previous function segment if it was empty. */
- bfun = VEC_last (btrace_fun_p, btinfo->functions);
+ 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);
}
@@ -556,11 +550,11 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
DEBUG_FTRACE ("no symbol at %s", core_addr_to_string_nz (pc));
/* If we didn't have a function, we create one. */
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ 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_p, btinfo->functions);
+ bfun = VEC_last (btrace_fun_s, btinfo->functions);
if (bfun->errcode != 0)
return ftrace_new_function (btinfo, mfun, fun);
@@ -730,12 +724,12 @@ ftrace_compute_global_level_offset (struct btrace_thread_info *btinfo)
if (btinfo == NULL)
return;
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
return;
level = INT_MAX;
- length = VEC_length (btrace_fun_p, btinfo->functions);
- for (i = 0; VEC_iterate (btrace_fun_p, btinfo->functions, i, bfun); ++i)
+ 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
@@ -1044,7 +1038,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
btinfo = &tp->btrace;
blk = VEC_length (btrace_block_s, btrace->blocks);
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
level = INT_MAX;
else
level = -btinfo->level;
@@ -1216,7 +1210,7 @@ ftrace_add_pt (struct btrace_thread_info *btinfo,
break;
/* Look for gaps in the trace - unless we're at the beginning. */
- if (!VEC_empty (btrace_fun_p, btinfo->functions))
+ 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
@@ -1347,7 +1341,7 @@ btrace_compute_ftrace_pt (struct thread_info *tp,
return;
btinfo = &tp->btrace;
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
level = INT_MAX;
else
level = -btinfo->level;
@@ -1388,7 +1382,7 @@ 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 && !VEC_empty (btrace_fun_p,
+ if (error.reason == RETURN_QUIT && !VEC_empty (btrace_fun_s,
btinfo->functions))
ftrace_new_gap (btinfo, BDE_PT_USER_QUIT, gaps);
@@ -1610,10 +1604,10 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
btrace_block_s *first_new_block;
btinfo = &tp->btrace;
- gdb_assert (!VEC_empty (btrace_fun_p, btinfo->functions));
+ gdb_assert (!VEC_empty (btrace_fun_s, btinfo->functions));
gdb_assert (!VEC_empty (btrace_block_s, btrace->blocks));
- last_bfun = VEC_last (btrace_fun_p, btinfo->functions);
+ last_bfun = VEC_last (btrace_fun_s, btinfo->functions);
/* If the existing trace ends with a gap, we just glue the traces
together. We need to drop the last (i.e. chronologically first) block
@@ -1842,7 +1836,7 @@ btrace_fetch (struct thread_info *tp)
make_cleanup_btrace_data (&btrace);
/* Let's first try to extend the trace we already have. */
- if (!VEC_empty (btrace_fun_p, btinfo->functions))
+ if (!VEC_empty (btrace_fun_s, btinfo->functions))
{
errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_DELTA);
if (errcode == 0)
@@ -1907,13 +1901,10 @@ btrace_clear (struct thread_info *tp)
btinfo = &tp->btrace;
- for (i = 0; VEC_iterate (btrace_fun_p, btinfo->functions, i, it); ++i)
- {
- VEC_free (btrace_insn_s, it->insn);
- xfree (it);
- }
+ for (i = 0; VEC_iterate (btrace_fun_s, btinfo->functions, i, it); ++i)
+ VEC_free (btrace_insn_s, it->insn);
- VEC_free (btrace_fun_p, btinfo->functions);
+ VEC_free (btrace_fun_s, btinfo->functions);
btinfo->ngaps = 0;
@@ -2261,7 +2252,7 @@ btrace_insn_get (const struct btrace_insn_iterator *it)
unsigned int index, end;
index = it->insn_index;
- bfun = VEC_index (btrace_fun_p, it->btinfo->functions, it->call_index);
+ bfun = VEC_index (btrace_fun_s, it->btinfo->functions, it->call_index);
/* Check if the iterator points to a gap in the trace. */
if (bfun->errcode != 0)
@@ -2282,7 +2273,7 @@ btrace_insn_get_error (const struct btrace_insn_iterator *it)
{
const struct btrace_function *bfun;
- bfun = VEC_index (btrace_fun_p, it->btinfo->functions, it->call_index);
+ bfun = VEC_index (btrace_fun_s, it->btinfo->functions, it->call_index);
return bfun->errcode;
}
@@ -2293,7 +2284,7 @@ btrace_insn_number (const struct btrace_insn_iterator *it)
{
const struct btrace_function *bfun;
- bfun = VEC_index (btrace_fun_p, it->btinfo->functions, it->call_index);
+ bfun = VEC_index (btrace_fun_s, it->btinfo->functions, it->call_index);
return bfun->insn_offset + it->insn_index;
}
@@ -2303,7 +2294,7 @@ void
btrace_insn_begin (struct btrace_insn_iterator *it,
const struct btrace_thread_info *btinfo)
{
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
error (_("No trace."));
it->btinfo = btinfo;
@@ -2320,10 +2311,10 @@ btrace_insn_end (struct btrace_insn_iterator *it,
const struct btrace_function *bfun;
unsigned int length;
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
error (_("No trace."));
- bfun = VEC_last (btrace_fun_p, btinfo->functions);
+ 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
@@ -2345,7 +2336,7 @@ btrace_insn_next (struct btrace_insn_iterator *it, unsigned int stride)
const struct btrace_function *bfun;
unsigned int index, steps;
- bfun = VEC_index (btrace_fun_p, it->btinfo->functions, it->call_index);
+ bfun = VEC_index (btrace_fun_s, it->btinfo->functions, it->call_index);
steps = 0;
index = it->insn_index;
@@ -2427,7 +2418,7 @@ btrace_insn_prev (struct btrace_insn_iterator *it, unsigned int stride)
const struct btrace_function *bfun;
unsigned int index, steps;
- bfun = VEC_index (btrace_fun_p, it->btinfo->functions, it->call_index);
+ bfun = VEC_index (btrace_fun_s, it->btinfo->functions, it->call_index);
steps = 0;
index = it->insn_index;
@@ -2510,16 +2501,16 @@ btrace_find_insn_by_number (struct btrace_insn_iterator *it,
const struct btrace_function *bfun;
unsigned int upper, lower;
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
return 0;
lower = 0;
- bfun = VEC_index (btrace_fun_p, btinfo->functions, lower);
+ bfun = VEC_index (btrace_fun_s, btinfo->functions, lower);
if (number < bfun->insn_offset)
return 0;
- upper = VEC_length (btrace_fun_p, btinfo->functions) - 1;
- bfun = VEC_index (btrace_fun_p, btinfo->functions, upper);
+ upper = VEC_length (btrace_fun_s, btinfo->functions) - 1;
+ bfun = VEC_index (btrace_fun_s, btinfo->functions, upper);
if (number >= bfun->insn_offset + ftrace_call_num_insn (bfun))
return 0;
@@ -2528,7 +2519,7 @@ btrace_find_insn_by_number (struct btrace_insn_iterator *it,
{
const unsigned int average = lower + (upper - lower) / 2;
- bfun = VEC_index (btrace_fun_p, btinfo->functions, average);
+ bfun = VEC_index (btrace_fun_s, btinfo->functions, average);
if (number < bfun->insn_offset)
{
@@ -2559,10 +2550,10 @@ btrace_ends_with_single_insn (const struct btrace_thread_info *btinfo)
{
const btrace_function *bfun;
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
return 0;
- bfun = VEC_last (btrace_fun_p, btinfo->functions);
+ bfun = VEC_last (btrace_fun_s, btinfo->functions);
if (bfun->errcode != 0)
return 0;
@@ -2574,10 +2565,10 @@ btrace_ends_with_single_insn (const struct btrace_thread_info *btinfo)
const struct btrace_function *
btrace_call_get (const struct btrace_call_iterator *it)
{
- if (it->index >= VEC_length (btrace_fun_p, it->btinfo->functions))
+ if (it->index >= VEC_length (btrace_fun_s, it->btinfo->functions))
return NULL;
- return VEC_index (btrace_fun_p, it->btinfo->functions, it->index);
+ return VEC_index (btrace_fun_s, it->btinfo->functions, it->index);
}
/* See btrace.h. */
@@ -2585,7 +2576,7 @@ btrace_call_get (const struct btrace_call_iterator *it)
unsigned int
btrace_call_number (const struct btrace_call_iterator *it)
{
- const unsigned int length = VEC_length (btrace_fun_p, it->btinfo->functions);
+ const unsigned int length = VEC_length (btrace_fun_s, it->btinfo->functions);
/* If the last function segment contains only a single instruction (i.e. the
current instruction), skip it. */
@@ -2601,7 +2592,7 @@ void
btrace_call_begin (struct btrace_call_iterator *it,
const struct btrace_thread_info *btinfo)
{
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
error (_("No trace."));
it->btinfo = btinfo;
@@ -2614,11 +2605,11 @@ void
btrace_call_end (struct btrace_call_iterator *it,
const struct btrace_thread_info *btinfo)
{
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ if (VEC_empty (btrace_fun_s, btinfo->functions))
error (_("No trace."));
it->btinfo = btinfo;
- it->index = VEC_length (btrace_fun_p, it->btinfo->functions);
+ it->index = VEC_length (btrace_fun_s, it->btinfo->functions);
}
/* See btrace.h. */
@@ -2626,7 +2617,7 @@ btrace_call_end (struct btrace_call_iterator *it,
unsigned int
btrace_call_next (struct btrace_call_iterator *it, unsigned int stride)
{
- const unsigned int length = VEC_length (btrace_fun_p, it->btinfo->functions);
+ const unsigned int length = VEC_length (btrace_fun_s, it->btinfo->functions);
if (it->index + stride < length - 1)
/* Default case: Simply advance the iterator. */
@@ -2662,7 +2653,7 @@ btrace_call_next (struct btrace_call_iterator *it, unsigned int stride)
unsigned int
btrace_call_prev (struct btrace_call_iterator *it, unsigned int stride)
{
- const unsigned int length = VEC_length (btrace_fun_p, it->btinfo->functions);
+ const unsigned int length = VEC_length (btrace_fun_s, it->btinfo->functions);
int steps = 0;
gdb_assert (it->index <= length);
@@ -2708,7 +2699,7 @@ btrace_find_call_by_number (struct btrace_call_iterator *it,
const struct btrace_thread_info *btinfo,
unsigned int number)
{
- const unsigned int length = VEC_length (btrace_fun_p, btinfo->functions);
+ const unsigned int length = VEC_length (btrace_fun_s, btinfo->functions);
if ((number == 0) || (number > length))
return 0;
@@ -2766,7 +2757,7 @@ btrace_is_empty (struct thread_info *tp)
btinfo = &tp->btrace;
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ 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 7a7e3e5..5febef3 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -181,8 +181,9 @@ struct btrace_function
btrace_function_flags flags;
};
-typedef struct btrace_function *btrace_fun_p;
-DEF_VEC_P (btrace_fun_p);
+/* A vector of branch trace function segments. */
+typedef struct btrace_function btrace_fun_s;
+DEF_VEC_O (btrace_fun_s);
/* A branch trace instruction iterator. */
struct btrace_insn_iterator
@@ -326,9 +327,10 @@ struct btrace_thread_info
/* The raw branch trace data for the below branch trace. */
struct btrace_data data;
- /* Vector of pointer to decoded function segments. These are in execution
- order with the first element == BEGIN and the last element == END. */
- VEC (btrace_fun_p) *functions;
+ /* Vector of decoded function segments in execution flow order. Note that
+ the numbering for btrace function segments starts with 1, so function
+ segment i will be at index (i - 1). */
+ VEC (btrace_fun_s) *functions;
/* The function level offset. When added to each function's LEVEL,
this normalizes the function levels such that the smallest level
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index e7a7cb4..7c8905b 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1592,7 +1592,7 @@ record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
gdb_assert (bfun != NULL);
while (bfun->prev != 0)
- bfun = VEC_index (btrace_fun_p, cache->tp->btrace.functions,
+ bfun = VEC_index (btrace_fun_s, cache->tp->btrace.functions,
bfun->prev - 1);
code = get_frame_func (this_frame);
@@ -1634,7 +1634,7 @@ record_btrace_frame_prev_register (struct frame_info *this_frame,
throw_error (NOT_AVAILABLE_ERROR,
_("No caller in btrace record history"));
- caller = VEC_index (btrace_fun_p, cache->tp->btrace.functions, bfun->up - 1);
+ caller = VEC_index (btrace_fun_s, cache->tp->btrace.functions, bfun->up - 1);
if ((bfun->flags & BFUN_UP_LINKS_TO_RET) != 0)
{
@@ -1680,7 +1680,7 @@ record_btrace_frame_sniffer (const struct frame_unwind *self,
replay = tp->btrace.replay;
if (replay != NULL)
- bfun = VEC_index (btrace_fun_p, replay->btinfo->functions,
+ bfun = VEC_index (btrace_fun_s, replay->btinfo->functions,
replay->call_index);
}
else
@@ -1689,7 +1689,7 @@ record_btrace_frame_sniffer (const struct frame_unwind *self,
callee = btrace_get_frame_function (next);
if (callee != NULL && (callee->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
- bfun = VEC_index (btrace_fun_p, tp->btrace.functions, callee->up - 1);
+ bfun = VEC_index (btrace_fun_s, tp->btrace.functions, callee->up - 1);
}
if (bfun == NULL)
@@ -1734,7 +1734,7 @@ record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
return 0;
tinfo = find_thread_ptid (inferior_ptid);
- bfun = VEC_index (btrace_fun_p, tinfo->btrace.functions, callee->up - 1);
+ bfun = VEC_index (btrace_fun_s, tinfo->btrace.functions, callee->up - 1);
DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
btrace_get_bfun_name (bfun), bfun->level);
@@ -1914,7 +1914,7 @@ record_btrace_start_replaying (struct thread_info *tp)
replay = NULL;
/* We can't start replaying without trace. */
- if (VEC_empty (btrace_fun_p, btinfo->functions))
+ 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