aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/btrace.c22
2 files changed, 18 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 98e13ea..2a601a9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2016-10-28 Markus Metzger <markus.t.metzger@intel.com>
+ * btrace.c (ftrace_new_return): Start from the previous function's
+ level if we can't find a matching call for a return.
+
+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>
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 445f0a4..10b6db4 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -387,16 +387,12 @@ ftrace_new_return (struct btrace_function *prev,
/* There is no call in PREV's back trace. We assume that the
branch trace did not include it. */
- /* Let's find the topmost call function - this skips tail calls. */
+ /* Let's find the topmost function and add a new caller for it.
+ This should handle a series of initial tail calls. */
while (prev->up != NULL)
prev = prev->up;
- /* We maintain levels for a series of returns for which we have
- not seen the calls.
- We start at the preceding function's level in case this has
- already been a return for which we have not seen the call.
- We start at level 0 otherwise, to handle tail calls correctly. */
- bfun->level = std::min (0, prev->level) - 1;
+ bfun->level = prev->level - 1;
/* Fix up the call stack for PREV. */
ftrace_fixup_caller (prev, bfun, BFUN_UP_LINKS_TO_RET);
@@ -406,8 +402,16 @@ ftrace_new_return (struct btrace_function *prev,
else
{
/* There is a call in PREV's back trace to which we should have
- returned. Let's remain at this level. */
- bfun->level = prev->level;
+ returned but didn't. Let's start a new, separate back trace
+ from PREV's level. */
+ bfun->level = prev->level - 1;
+
+ /* We fix up the back trace for PREV but leave other function segments
+ on the same level as they are.
+ This should handle things like schedule () correctly where we're
+ switching contexts. */
+ prev->up = bfun;
+ prev->flags = BFUN_UP_LINKS_TO_RET;
ftrace_debug (bfun, "new return - unknown caller");
}