btrace: Store btrace_insn in an std::vector
Because it contains a non-POD type field (flags), the type btrace_insn should be new'ed/delete'd. Replace the VEC (btrace_insn_s) in btrace_function with an std::vector. gdb/ChangeLog: * btrace.h (btrace_insn_s, DEF_VEC_O (btrace_insn_s)): Remove. (btrace_function) <insn>: Change type to use std::vector. * btrace.c (ftrace_debug, ftrace_call_num_insn, ftrace_find_call, ftrace_new_gap, ftrace_update_function, ftrace_update_insns, ftrace_compute_global_level_offset, btrace_stitch_bts, btrace_clear, btrace_insn_get, btrace_insn_end, btrace_insn_next, btrace_insn_prev): Adjust to change to std::vector. (ftrace_update_insns): Adjust to change to std::vector, change type of INSN parameter. (btrace_compute_ftrace_bts): Adjust call to ftrace_update_insns. * record-btrace.c (btrace_call_history_insn_range, btrace_compute_src_line_range, record_btrace_frame_prev_register): Adjust to change to std::vector. * python/py-record-btrace.c (recpy_bt_func_instructions): Adjust to change to std::vector.
This commit is contained in:
parent
a826403eb6
commit
0860c437cb
5 changed files with 53 additions and 52 deletions
|
@ -1,3 +1,23 @@
|
||||||
|
2017-09-04 Simon Marchi <simon.marchi@ericsson.com>
|
||||||
|
|
||||||
|
* btrace.h (btrace_insn_s, DEF_VEC_O (btrace_insn_s)): Remove.
|
||||||
|
(btrace_function) <insn>: Change type to use std::vector.
|
||||||
|
* btrace.c (ftrace_debug, ftrace_call_num_insn,
|
||||||
|
ftrace_find_call, ftrace_new_gap, ftrace_update_function,
|
||||||
|
ftrace_update_insns, ftrace_compute_global_level_offset,
|
||||||
|
btrace_stitch_bts, btrace_clear, btrace_insn_get,
|
||||||
|
btrace_insn_end, btrace_insn_next, btrace_insn_prev): Adjust to
|
||||||
|
change to std::vector.
|
||||||
|
(ftrace_update_insns): Adjust to change to std::vector, change
|
||||||
|
type of INSN parameter.
|
||||||
|
(btrace_compute_ftrace_bts): Adjust call to ftrace_update_insns.
|
||||||
|
* record-btrace.c (btrace_call_history_insn_range,
|
||||||
|
btrace_compute_src_line_range,
|
||||||
|
record_btrace_frame_prev_register): Adjust to change to
|
||||||
|
std::vector.
|
||||||
|
* python/py-record-btrace.c (recpy_bt_func_instructions): Adjust
|
||||||
|
to change to std::vector.
|
||||||
|
|
||||||
2017-09-03 Tom Tromey <tom@tromey.com>
|
2017-09-03 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* corefile.c (reopen_exec_file): Use std::string.
|
* corefile.c (reopen_exec_file): Use std::string.
|
||||||
|
|
59
gdb/btrace.c
59
gdb/btrace.c
|
@ -131,7 +131,7 @@ ftrace_debug (const struct btrace_function *bfun, const char *prefix)
|
||||||
level = bfun->level;
|
level = bfun->level;
|
||||||
|
|
||||||
ibegin = bfun->insn_offset;
|
ibegin = bfun->insn_offset;
|
||||||
iend = ibegin + VEC_length (btrace_insn_s, bfun->insn);
|
iend = ibegin + bfun->insn.size ();
|
||||||
|
|
||||||
DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, insn = [%u; %u)",
|
DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, insn = [%u; %u)",
|
||||||
prefix, fun, file, level, ibegin, iend);
|
prefix, fun, file, level, ibegin, iend);
|
||||||
|
@ -149,7 +149,7 @@ ftrace_call_num_insn (const struct btrace_function* bfun)
|
||||||
if (bfun->errcode != 0)
|
if (bfun->errcode != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return VEC_length (btrace_insn_s, bfun->insn);
|
return bfun->insn.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the function segment with the given NUMBER or NULL if no such segment
|
/* Return the function segment with the given NUMBER or NULL if no such segment
|
||||||
|
@ -390,15 +390,13 @@ ftrace_find_call (struct btrace_thread_info *btinfo,
|
||||||
{
|
{
|
||||||
for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
|
for (; bfun != NULL; bfun = ftrace_find_call_by_number (btinfo, bfun->up))
|
||||||
{
|
{
|
||||||
struct btrace_insn *last;
|
|
||||||
|
|
||||||
/* Skip gaps. */
|
/* Skip gaps. */
|
||||||
if (bfun->errcode != 0)
|
if (bfun->errcode != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
last = VEC_last (btrace_insn_s, bfun->insn);
|
btrace_insn &last = bfun->insn.back ();
|
||||||
|
|
||||||
if (last->iclass == BTRACE_INSN_CALL)
|
if (last.iclass == BTRACE_INSN_CALL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,7 +526,7 @@ ftrace_new_gap (struct btrace_thread_info *btinfo, int errcode,
|
||||||
{
|
{
|
||||||
/* We hijack the previous function segment if it was empty. */
|
/* We hijack the previous function segment if it was empty. */
|
||||||
bfun = &btinfo->functions.back ();
|
bfun = &btinfo->functions.back ();
|
||||||
if (bfun->errcode != 0 || !VEC_empty (btrace_insn_s, bfun->insn))
|
if (bfun->errcode != 0 || !bfun->insn.empty ())
|
||||||
bfun = ftrace_new_function (btinfo, NULL, NULL);
|
bfun = ftrace_new_function (btinfo, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,7 +548,6 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
|
||||||
struct bound_minimal_symbol bmfun;
|
struct bound_minimal_symbol bmfun;
|
||||||
struct minimal_symbol *mfun;
|
struct minimal_symbol *mfun;
|
||||||
struct symbol *fun;
|
struct symbol *fun;
|
||||||
struct btrace_insn *last;
|
|
||||||
struct btrace_function *bfun;
|
struct btrace_function *bfun;
|
||||||
|
|
||||||
/* Try to determine the function we're in. We use both types of symbols
|
/* Try to determine the function we're in. We use both types of symbols
|
||||||
|
@ -575,9 +572,9 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
|
||||||
/* Check the last instruction, if we have one.
|
/* Check the last instruction, if we have one.
|
||||||
We do this check first, since it allows us to fill in the call stack
|
We do this check first, since it allows us to fill in the call stack
|
||||||
links in addition to the normal flow links. */
|
links in addition to the normal flow links. */
|
||||||
last = NULL;
|
btrace_insn *last = NULL;
|
||||||
if (!VEC_empty (btrace_insn_s, bfun->insn))
|
if (!bfun->insn.empty ())
|
||||||
last = VEC_last (btrace_insn_s, bfun->insn);
|
last = &bfun->insn.back ();
|
||||||
|
|
||||||
if (last != NULL)
|
if (last != NULL)
|
||||||
{
|
{
|
||||||
|
@ -648,10 +645,9 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
|
||||||
/* Add the instruction at PC to BFUN's instructions. */
|
/* Add the instruction at PC to BFUN's instructions. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ftrace_update_insns (struct btrace_function *bfun,
|
ftrace_update_insns (struct btrace_function *bfun, const btrace_insn &insn)
|
||||||
const struct btrace_insn *insn)
|
|
||||||
{
|
{
|
||||||
VEC_safe_push (btrace_insn_s, bfun->insn, insn);
|
bfun->insn.push_back (insn);
|
||||||
|
|
||||||
if (record_debug > 1)
|
if (record_debug > 1)
|
||||||
ftrace_debug (bfun, "update insn");
|
ftrace_debug (bfun, "update insn");
|
||||||
|
@ -747,7 +743,7 @@ ftrace_compute_global_level_offset (struct btrace_thread_info *btinfo)
|
||||||
really part of the trace. If it contains just this one instruction, we
|
really part of the trace. If it contains just this one instruction, we
|
||||||
ignore the segment. */
|
ignore the segment. */
|
||||||
struct btrace_function *last = &btinfo->functions.back();
|
struct btrace_function *last = &btinfo->functions.back();
|
||||||
if (VEC_length (btrace_insn_s, last->insn) != 1)
|
if (last->insn.size () != 1)
|
||||||
level = std::min (level, last->level);
|
level = std::min (level, last->level);
|
||||||
|
|
||||||
DEBUG_FTRACE ("setting global level offset: %d", -level);
|
DEBUG_FTRACE ("setting global level offset: %d", -level);
|
||||||
|
@ -1104,7 +1100,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
|
||||||
insn.iclass = ftrace_classify_insn (gdbarch, pc);
|
insn.iclass = ftrace_classify_insn (gdbarch, pc);
|
||||||
insn.flags = 0;
|
insn.flags = 0;
|
||||||
|
|
||||||
ftrace_update_insns (bfun, &insn);
|
ftrace_update_insns (bfun, insn);
|
||||||
|
|
||||||
/* We're done once we pushed the instruction at the end. */
|
/* We're done once we pushed the instruction at the end. */
|
||||||
if (block->end == pc)
|
if (block->end == pc)
|
||||||
|
@ -1682,7 +1678,6 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
|
||||||
{
|
{
|
||||||
struct btrace_thread_info *btinfo;
|
struct btrace_thread_info *btinfo;
|
||||||
struct btrace_function *last_bfun;
|
struct btrace_function *last_bfun;
|
||||||
struct btrace_insn *last_insn;
|
|
||||||
btrace_block_s *first_new_block;
|
btrace_block_s *first_new_block;
|
||||||
|
|
||||||
btinfo = &tp->btrace;
|
btinfo = &tp->btrace;
|
||||||
|
@ -1694,7 +1689,7 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
|
||||||
/* If the existing trace ends with a gap, we just glue the traces
|
/* 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
|
together. We need to drop the last (i.e. chronologically first) block
|
||||||
of the new trace, though, since we can't fill in the start address.*/
|
of the new trace, though, since we can't fill in the start address.*/
|
||||||
if (VEC_empty (btrace_insn_s, last_bfun->insn))
|
if (last_bfun->insn.empty ())
|
||||||
{
|
{
|
||||||
VEC_pop (btrace_block_s, btrace->blocks);
|
VEC_pop (btrace_block_s, btrace->blocks);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1704,7 +1699,7 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
|
||||||
chronologically first block in the new trace is the last block in
|
chronologically first block in the new trace is the last block in
|
||||||
the new trace's block vector. */
|
the new trace's block vector. */
|
||||||
first_new_block = VEC_last (btrace_block_s, btrace->blocks);
|
first_new_block = VEC_last (btrace_block_s, btrace->blocks);
|
||||||
last_insn = VEC_last (btrace_insn_s, last_bfun->insn);
|
const btrace_insn &last_insn = last_bfun->insn.back ();
|
||||||
|
|
||||||
/* If the current PC at the end of the block is the same as in our current
|
/* If the current PC at the end of the block is the same as in our current
|
||||||
trace, there are two explanations:
|
trace, there are two explanations:
|
||||||
|
@ -1714,19 +1709,19 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
|
||||||
entries.
|
entries.
|
||||||
In the second case, the delta trace vector should contain exactly one
|
In the second case, the delta trace vector should contain exactly one
|
||||||
entry for the partial block containing the current PC. Remove it. */
|
entry for the partial block containing the current PC. Remove it. */
|
||||||
if (first_new_block->end == last_insn->pc
|
if (first_new_block->end == last_insn.pc
|
||||||
&& VEC_length (btrace_block_s, btrace->blocks) == 1)
|
&& VEC_length (btrace_block_s, btrace->blocks) == 1)
|
||||||
{
|
{
|
||||||
VEC_pop (btrace_block_s, btrace->blocks);
|
VEC_pop (btrace_block_s, btrace->blocks);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ("stitching %s to %s", ftrace_print_insn_addr (last_insn),
|
DEBUG ("stitching %s to %s", ftrace_print_insn_addr (&last_insn),
|
||||||
core_addr_to_string_nz (first_new_block->end));
|
core_addr_to_string_nz (first_new_block->end));
|
||||||
|
|
||||||
/* Do a simple sanity check to make sure we don't accidentally end up
|
/* Do a simple sanity check to make sure we don't accidentally end up
|
||||||
with a bad block. This should not occur in practice. */
|
with a bad block. This should not occur in practice. */
|
||||||
if (first_new_block->end < last_insn->pc)
|
if (first_new_block->end < last_insn.pc)
|
||||||
{
|
{
|
||||||
warning (_("Error while trying to read delta trace. Falling back to "
|
warning (_("Error while trying to read delta trace. Falling back to "
|
||||||
"a full read."));
|
"a full read."));
|
||||||
|
@ -1735,16 +1730,16 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
|
||||||
|
|
||||||
/* We adjust the last block to start at the end of our current trace. */
|
/* We adjust the last block to start at the end of our current trace. */
|
||||||
gdb_assert (first_new_block->begin == 0);
|
gdb_assert (first_new_block->begin == 0);
|
||||||
first_new_block->begin = last_insn->pc;
|
first_new_block->begin = last_insn.pc;
|
||||||
|
|
||||||
/* We simply pop the last insn so we can insert it again as part of
|
/* We simply pop the last insn so we can insert it again as part of
|
||||||
the normal branch trace computation.
|
the normal branch trace computation.
|
||||||
Since instruction iterators are based on indices in the instructions
|
Since instruction iterators are based on indices in the instructions
|
||||||
vector, we don't leave any pointers dangling. */
|
vector, we don't leave any pointers dangling. */
|
||||||
DEBUG ("pruning insn at %s for stitching",
|
DEBUG ("pruning insn at %s for stitching",
|
||||||
ftrace_print_insn_addr (last_insn));
|
ftrace_print_insn_addr (&last_insn));
|
||||||
|
|
||||||
VEC_pop (btrace_insn_s, last_bfun->insn);
|
last_bfun->insn.pop_back ();
|
||||||
|
|
||||||
/* The instructions vector may become empty temporarily if this has
|
/* The instructions vector may become empty temporarily if this has
|
||||||
been the only instruction in this function segment.
|
been the only instruction in this function segment.
|
||||||
|
@ -1755,7 +1750,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
|
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
|
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. */
|
the beginning. To avoid this, we remove the entire old trace. */
|
||||||
if (last_bfun->number == 1 && VEC_empty (btrace_insn_s, last_bfun->insn))
|
if (last_bfun->number == 1 && last_bfun->insn.empty ())
|
||||||
btrace_clear (tp);
|
btrace_clear (tp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1980,8 +1975,6 @@ btrace_clear (struct thread_info *tp)
|
||||||
reinit_frame_cache ();
|
reinit_frame_cache ();
|
||||||
|
|
||||||
btinfo = &tp->btrace;
|
btinfo = &tp->btrace;
|
||||||
for (auto &bfun : btinfo->functions)
|
|
||||||
VEC_free (btrace_insn_s, bfun.insn);
|
|
||||||
|
|
||||||
btinfo->functions.clear ();
|
btinfo->functions.clear ();
|
||||||
btinfo->ngaps = 0;
|
btinfo->ngaps = 0;
|
||||||
|
@ -2337,11 +2330,11 @@ btrace_insn_get (const struct btrace_insn_iterator *it)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* The index is within the bounds of this function's instruction vector. */
|
/* The index is within the bounds of this function's instruction vector. */
|
||||||
end = VEC_length (btrace_insn_s, bfun->insn);
|
end = bfun->insn.size ();
|
||||||
gdb_assert (0 < end);
|
gdb_assert (0 < end);
|
||||||
gdb_assert (index < end);
|
gdb_assert (index < end);
|
||||||
|
|
||||||
return VEC_index (btrace_insn_s, bfun->insn, index);
|
return &bfun->insn[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See btrace.h. */
|
/* See btrace.h. */
|
||||||
|
@ -2387,7 +2380,7 @@ btrace_insn_end (struct btrace_insn_iterator *it,
|
||||||
error (_("No trace."));
|
error (_("No trace."));
|
||||||
|
|
||||||
bfun = &btinfo->functions.back ();
|
bfun = &btinfo->functions.back ();
|
||||||
length = VEC_length (btrace_insn_s, bfun->insn);
|
length = bfun->insn.size ();
|
||||||
|
|
||||||
/* The last function may either be a gap or it contains the current
|
/* The last function may either be a gap or it contains the current
|
||||||
instruction, which is one past the end of the execution trace; ignore
|
instruction, which is one past the end of the execution trace; ignore
|
||||||
|
@ -2416,7 +2409,7 @@ btrace_insn_next (struct btrace_insn_iterator *it, unsigned int stride)
|
||||||
{
|
{
|
||||||
unsigned int end, space, adv;
|
unsigned int end, space, adv;
|
||||||
|
|
||||||
end = VEC_length (btrace_insn_s, bfun->insn);
|
end = bfun->insn.size ();
|
||||||
|
|
||||||
/* An empty function segment represents a gap in the trace. We count
|
/* An empty function segment represents a gap in the trace. We count
|
||||||
it as one instruction. */
|
it as one instruction. */
|
||||||
|
@ -2509,7 +2502,7 @@ btrace_insn_prev (struct btrace_insn_iterator *it, unsigned int stride)
|
||||||
|
|
||||||
/* We point to one after the last instruction in the new function. */
|
/* We point to one after the last instruction in the new function. */
|
||||||
bfun = prev;
|
bfun = prev;
|
||||||
index = VEC_length (btrace_insn_s, bfun->insn);
|
index = bfun->insn.size ();
|
||||||
|
|
||||||
/* An empty function segment represents a gap in the trace. We count
|
/* An empty function segment represents a gap in the trace. We count
|
||||||
it as one instruction. */
|
it as one instruction. */
|
||||||
|
|
|
@ -81,10 +81,6 @@ struct btrace_insn
|
||||||
btrace_insn_flags flags;
|
btrace_insn_flags flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A vector of branch trace instructions. */
|
|
||||||
typedef struct btrace_insn btrace_insn_s;
|
|
||||||
DEF_VEC_O (btrace_insn_s);
|
|
||||||
|
|
||||||
/* Flags for btrace function segments. */
|
/* Flags for btrace function segments. */
|
||||||
enum btrace_function_flag
|
enum btrace_function_flag
|
||||||
{
|
{
|
||||||
|
@ -161,7 +157,7 @@ struct btrace_function
|
||||||
/* The instructions in this function segment.
|
/* The instructions in this function segment.
|
||||||
The instruction vector will be empty if the function segment
|
The instruction vector will be empty if the function segment
|
||||||
represents a decode error. */
|
represents a decode error. */
|
||||||
VEC (btrace_insn_s) *insn = NULL;
|
std::vector<btrace_insn> insn;
|
||||||
|
|
||||||
/* The error code of a decode error that led to a gap.
|
/* The error code of a decode error that led to a gap.
|
||||||
Must be zero unless INSN is empty; non-zero otherwise. */
|
Must be zero unless INSN is empty; non-zero otherwise. */
|
||||||
|
|
|
@ -376,7 +376,7 @@ recpy_bt_func_instructions (PyObject *self, void *closure)
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = VEC_length (btrace_insn_s, func->insn);
|
len = func->insn.size ();
|
||||||
|
|
||||||
/* Gaps count as one instruction. */
|
/* Gaps count as one instruction. */
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
|
|
|
@ -891,7 +891,7 @@ btrace_call_history_insn_range (struct ui_out *uiout,
|
||||||
{
|
{
|
||||||
unsigned int begin, end, size;
|
unsigned int begin, end, size;
|
||||||
|
|
||||||
size = VEC_length (btrace_insn_s, bfun->insn);
|
size = bfun->insn.size ();
|
||||||
gdb_assert (size > 0);
|
gdb_assert (size > 0);
|
||||||
|
|
||||||
begin = bfun->insn_offset;
|
begin = bfun->insn_offset;
|
||||||
|
@ -911,10 +911,8 @@ static void
|
||||||
btrace_compute_src_line_range (const struct btrace_function *bfun,
|
btrace_compute_src_line_range (const struct btrace_function *bfun,
|
||||||
int *pbegin, int *pend)
|
int *pbegin, int *pend)
|
||||||
{
|
{
|
||||||
struct btrace_insn *insn;
|
|
||||||
struct symtab *symtab;
|
struct symtab *symtab;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
unsigned int idx;
|
|
||||||
int begin, end;
|
int begin, end;
|
||||||
|
|
||||||
begin = INT_MAX;
|
begin = INT_MAX;
|
||||||
|
@ -926,11 +924,11 @@ btrace_compute_src_line_range (const struct btrace_function *bfun,
|
||||||
|
|
||||||
symtab = symbol_symtab (sym);
|
symtab = symbol_symtab (sym);
|
||||||
|
|
||||||
for (idx = 0; VEC_iterate (btrace_insn_s, bfun->insn, idx, insn); ++idx)
|
for (const btrace_insn &insn : bfun->insn)
|
||||||
{
|
{
|
||||||
struct symtab_and_line sal;
|
struct symtab_and_line sal;
|
||||||
|
|
||||||
sal = find_pc_line (insn->pc, 0);
|
sal = find_pc_line (insn.pc, 0);
|
||||||
if (sal.symtab != symtab || sal.line == 0)
|
if (sal.symtab != symtab || sal.line == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1615,7 +1613,6 @@ record_btrace_frame_prev_register (struct frame_info *this_frame,
|
||||||
{
|
{
|
||||||
const struct btrace_frame_cache *cache;
|
const struct btrace_frame_cache *cache;
|
||||||
const struct btrace_function *bfun, *caller;
|
const struct btrace_function *bfun, *caller;
|
||||||
const struct btrace_insn *insn;
|
|
||||||
struct btrace_call_iterator it;
|
struct btrace_call_iterator it;
|
||||||
struct gdbarch *gdbarch;
|
struct gdbarch *gdbarch;
|
||||||
CORE_ADDR pc;
|
CORE_ADDR pc;
|
||||||
|
@ -1638,15 +1635,10 @@ record_btrace_frame_prev_register (struct frame_info *this_frame,
|
||||||
caller = btrace_call_get (&it);
|
caller = btrace_call_get (&it);
|
||||||
|
|
||||||
if ((bfun->flags & BFUN_UP_LINKS_TO_RET) != 0)
|
if ((bfun->flags & BFUN_UP_LINKS_TO_RET) != 0)
|
||||||
{
|
pc = caller->insn.front ().pc;
|
||||||
insn = VEC_index (btrace_insn_s, caller->insn, 0);
|
|
||||||
pc = insn->pc;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
insn = VEC_last (btrace_insn_s, caller->insn);
|
pc = caller->insn.back ().pc;
|
||||||
pc = insn->pc;
|
|
||||||
|
|
||||||
pc += gdb_insn_length (gdbarch, pc);
|
pc += gdb_insn_length (gdbarch, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue