btrace: compute line range when printing
authorMarkus Metzger <markus.t.metzger@intel.com>
Tue, 24 Jun 2014 12:25:50 +0000 (14:25 +0200)
committerMarkus Metzger <markus.t.metzger@intel.com>
Tue, 3 Mar 2015 08:50:06 +0000 (09:50 +0100)
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.

gdb/ChangeLog
gdb/btrace.c
gdb/btrace.h
gdb/record-btrace.c

index 68c55c14882f5ff8732e22e23cf90598df365666..09a675fd83a3fd1a4e6a7a0bc8d81a26d518b401 100644 (file)
@@ -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
index 206e692876fa630a1e0ae0ba2c67d7d04d3b1c71..c5d3ee19fc07a301eddac1e90ef14fa14a731750 100644 (file)
@@ -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)
index 0ddd4c1fa099c871844126b3be27cf343dcd8d40..36bf5001f2cdf66d54983eaddac9b7611a530bc2 100644 (file)
@@ -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;
 };
index 35c775a04b69496907c82d74a0c9da5eabff48b7..af7b65feda253181d79634c72edc88b5ff3cd4aa 100644 (file)
@@ -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;