btrace: compute line range when printing
The "record function-call-history" command prints the range of source lines for a function segment when given the /l modifier. This information is computed for the entire execution history when processing the recorded branch trace. To speed up the initial trace processing, we compute the information when we print a function segment and only if requested. The computation is fast enough (due to the limited scope) that it is not worth storing the data in struct btrace_function, anymore. gdb/ * btrace.h (btrace_function) <lbegin, lend>: Remove. * btrace.c (ftrace_debug): Do not print the line range. (ftrace_skip_file, ftrace_update_lines): Remove. (ftrace_new_function): Remove lbegin and lend initialization. (btrace_compute_ftrace_bts): Remove call to ftrace_update_lines. * record-btrace.c (btrace_compute_src_line_range): New. (btrace_call_history_src_line): Call btrace_compute_src_line_range.
This commit is contained in:
parent
95e50b2723
commit
ce0dfbeaad
|
@ -1,3 +1,13 @@
|
|||
2015-03-03 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
* btrace.h (btrace_function) <lbegin, lend>: Remove.
|
||||
* btrace.c (ftrace_debug): Do not print the line range.
|
||||
(ftrace_skip_file, ftrace_update_lines): Remove.
|
||||
(ftrace_new_function): Remove lbegin and lend initialization.
|
||||
(btrace_compute_ftrace_bts): Remove call to ftrace_update_lines.
|
||||
* record-btrace.c (btrace_compute_src_line_range): New.
|
||||
(btrace_call_history_src_line): Call btrace_compute_src_line_range.
|
||||
|
||||
2015-03-02 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* infrun.c (follow_exec): Delete all threads of the process except
|
||||
|
|
68
gdb/btrace.c
68
gdb/btrace.c
|
@ -105,21 +105,17 @@ ftrace_debug (const struct btrace_function *bfun, const char *prefix)
|
|||
{
|
||||
const char *fun, *file;
|
||||
unsigned int ibegin, iend;
|
||||
int lbegin, lend, level;
|
||||
int level;
|
||||
|
||||
fun = ftrace_print_function_name (bfun);
|
||||
file = ftrace_print_filename (bfun);
|
||||
level = bfun->level;
|
||||
|
||||
lbegin = bfun->lbegin;
|
||||
lend = bfun->lend;
|
||||
|
||||
ibegin = bfun->insn_offset;
|
||||
iend = ibegin + VEC_length (btrace_insn_s, bfun->insn);
|
||||
|
||||
DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, lines = [%d; %d], "
|
||||
"insn = [%u; %u)", prefix, fun, file, level, lbegin, lend,
|
||||
ibegin, iend);
|
||||
DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, insn = [%u; %u)",
|
||||
prefix, fun, file, level, ibegin, iend);
|
||||
}
|
||||
|
||||
/* Return non-zero if BFUN does not match MFUN and FUN,
|
||||
|
@ -168,26 +164,6 @@ ftrace_function_switched (const struct btrace_function *bfun,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Return non-zero if we should skip this file when generating the function
|
||||
call history, zero otherwise.
|
||||
We would want to do that if, say, a macro that is defined in another file
|
||||
is expanded in this function. */
|
||||
|
||||
static int
|
||||
ftrace_skip_file (const struct btrace_function *bfun, const char *fullname)
|
||||
{
|
||||
struct symbol *sym;
|
||||
const char *bfile;
|
||||
|
||||
sym = bfun->sym;
|
||||
if (sym == NULL)
|
||||
return 1;
|
||||
|
||||
bfile = symtab_to_fullname (symbol_symtab (sym));
|
||||
|
||||
return (filename_cmp (bfile, fullname) != 0);
|
||||
}
|
||||
|
||||
/* Allocate and initialize a new branch trace function segment.
|
||||
PREV is the chronologically preceding function segment.
|
||||
MFUN and FUN are the symbol information we have for this function. */
|
||||
|
@ -205,10 +181,6 @@ ftrace_new_function (struct btrace_function *prev,
|
|||
bfun->sym = fun;
|
||||
bfun->flow.prev = prev;
|
||||
|
||||
/* We start with the identities of min and max, respectively. */
|
||||
bfun->lbegin = INT_MAX;
|
||||
bfun->lend = INT_MIN;
|
||||
|
||||
if (prev == NULL)
|
||||
{
|
||||
/* Start counting at one. */
|
||||
|
@ -543,39 +515,6 @@ ftrace_update_function (struct btrace_function *bfun, CORE_ADDR pc)
|
|||
return bfun;
|
||||
}
|
||||
|
||||
/* Update BFUN's source range with respect to the instruction at PC. */
|
||||
|
||||
static void
|
||||
ftrace_update_lines (struct btrace_function *bfun, CORE_ADDR pc)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
const char *fullname;
|
||||
|
||||
sal = find_pc_line (pc, 0);
|
||||
if (sal.symtab == NULL || sal.line == 0)
|
||||
{
|
||||
DEBUG_FTRACE ("no lines at %s", core_addr_to_string_nz (pc));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if we switched files. This could happen if, say, a macro that
|
||||
is defined in another file is expanded here. */
|
||||
fullname = symtab_to_fullname (sal.symtab);
|
||||
if (ftrace_skip_file (bfun, fullname))
|
||||
{
|
||||
DEBUG_FTRACE ("ignoring file at %s, file=%s",
|
||||
core_addr_to_string_nz (pc), fullname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the line range. */
|
||||
bfun->lbegin = min (bfun->lbegin, sal.line);
|
||||
bfun->lend = max (bfun->lend, sal.line);
|
||||
|
||||
if (record_debug > 1)
|
||||
ftrace_debug (bfun, "update lines");
|
||||
}
|
||||
|
||||
/* Add the instruction at PC to BFUN's instructions. */
|
||||
|
||||
static void
|
||||
|
@ -680,7 +619,6 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
|
|||
insn.iclass = ftrace_classify_insn (gdbarch, pc);
|
||||
|
||||
ftrace_update_insns (end, &insn);
|
||||
ftrace_update_lines (end, pc);
|
||||
|
||||
/* We're done once we pushed the instruction at the end. */
|
||||
if (block->end == pc)
|
||||
|
|
|
@ -150,9 +150,6 @@ struct btrace_function
|
|||
a fixup to normalize function levels so the smallest level is zero. */
|
||||
int level;
|
||||
|
||||
/* The source line range of this function segment (both inclusive). */
|
||||
int lbegin, lend;
|
||||
|
||||
/* A bit-vector of btrace_function_flag. */
|
||||
enum btrace_function_flag flags;
|
||||
};
|
||||
|
|
|
@ -721,6 +721,47 @@ btrace_call_history_insn_range (struct ui_out *uiout,
|
|||
ui_out_field_uint (uiout, "insn end", end);
|
||||
}
|
||||
|
||||
/* Compute the lowest and highest source line for the instructions in BFUN
|
||||
and return them in PBEGIN and PEND.
|
||||
Ignore instructions that can't be mapped to BFUN, e.g. instructions that
|
||||
result from inlining or macro expansion. */
|
||||
|
||||
static void
|
||||
btrace_compute_src_line_range (const struct btrace_function *bfun,
|
||||
int *pbegin, int *pend)
|
||||
{
|
||||
struct btrace_insn *insn;
|
||||
struct symtab *symtab;
|
||||
struct symbol *sym;
|
||||
unsigned int idx;
|
||||
int begin, end;
|
||||
|
||||
begin = INT_MAX;
|
||||
end = INT_MIN;
|
||||
|
||||
sym = bfun->sym;
|
||||
if (sym == NULL)
|
||||
goto out;
|
||||
|
||||
symtab = symbol_symtab (sym);
|
||||
|
||||
for (idx = 0; VEC_iterate (btrace_insn_s, bfun->insn, idx, insn); ++idx)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
sal = find_pc_line (insn->pc, 0);
|
||||
if (sal.symtab != symtab || sal.line == 0)
|
||||
continue;
|
||||
|
||||
begin = min (begin, sal.line);
|
||||
end = max (end, sal.line);
|
||||
}
|
||||
|
||||
out:
|
||||
*pbegin = begin;
|
||||
*pend = end;
|
||||
}
|
||||
|
||||
/* Print the source line information for a function call history line. */
|
||||
|
||||
static void
|
||||
|
@ -737,9 +778,7 @@ btrace_call_history_src_line (struct ui_out *uiout,
|
|||
ui_out_field_string (uiout, "file",
|
||||
symtab_to_filename_for_display (symbol_symtab (sym)));
|
||||
|
||||
begin = bfun->lbegin;
|
||||
end = bfun->lend;
|
||||
|
||||
btrace_compute_src_line_range (bfun, &begin, &end);
|
||||
if (end < begin)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue