btrace: update tail call heuristic
authorMarkus Metzger <markus.t.metzger@intel.com>
Tue, 12 Jan 2016 15:05:15 +0000 (16:05 +0100)
committerMarkus Metzger <markus.t.metzger@intel.com>
Fri, 28 Oct 2016 08:57:16 +0000 (10:57 +0200)
An unconditional jump to the start of a function typically indicates a tail
call.

If we can't determine the start of the function at the destination address, we
used to treat it as a tail call, as well.  This results in lots of tail calls
for code for which we don't have symbol information.

Restrict the heuristic to only consider jumps as tail calls that switch
functions in the case where we can't determine the start of a function.  This
effectively disables tail call detection for code without symbol information.

gdb/
* btrace.c (ftrace_update_function): Update tail call heuristic.

gdb/ChangeLog
gdb/btrace.c

index 350e5a627ddf414a145dff16d25de4a20349fea8..98e13ea9b6027f38ef96b88f65e77849fba507c5 100644 (file)
@@ -1,3 +1,7 @@
+2016-10-28  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * btrace.c (ftrace_update_function): Update tail call heuristic.
+
 2016-10-28  Markus Metzger  <markus.t.metzger@intel.com>
 
        * btrace.c (btrace_compute_ftrace_bts, ftrace_add_pt): Allow
index 648d49532bb0d80ef7f28bad25161521de367911..445f0a4c165d17534d6c808c6323811609e63fee 100644 (file)
@@ -529,10 +529,17 @@ ftrace_update_function (struct btrace_function *bfun, CORE_ADDR pc)
 
            start = get_pc_function_start (pc);
 
+           /* A jump to the start of a function is (typically) a tail call.  */
+           if (start == pc)
+             return ftrace_new_tailcall (bfun, mfun, fun);
+
            /* If we can't determine the function for PC, we treat a jump at
-              the end of the block as tail call.  */
-           if (start == 0 || start == pc)
+              the end of the block as tail call if we're switching functions
+              and as an intra-function branch if we don't.  */
+           if (start == 0 && ftrace_function_switched (bfun, mfun, fun))
              return ftrace_new_tailcall (bfun, mfun, fun);
+
+           break;
          }
        }
     }