aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/btrace.c19
2 files changed, 23 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 09a675f..3e9fa55 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2015-03-03 Markus Metzger <markus.t.metzger@intel.com>
+ * btrace.c (ftrace_update_function): Treat return as tailcall for
+ "_dl_runtime_resolve".
+
+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.
diff --git a/gdb/btrace.c b/gdb/btrace.c
index c5d3ee1..5436ee9 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -478,7 +478,24 @@ ftrace_update_function (struct btrace_function *bfun, CORE_ADDR pc)
switch (last->iclass)
{
case BTRACE_INSN_RETURN:
- return ftrace_new_return (bfun, mfun, fun);
+ {
+ const char *fname;
+
+ /* On some systems, _dl_runtime_resolve returns to the resolved
+ function instead of jumping to it. From our perspective,
+ however, this is a tailcall.
+ If we treated it as return, we wouldn't be able to find the
+ resolved function in our stack back trace. Hence, we would
+ lose the current stack back trace and start anew with an empty
+ back trace. When the resolved function returns, we would then
+ create a stack back trace with the same function names but
+ different frame id's. This will confuse stepping. */
+ fname = ftrace_print_function_name (bfun);
+ if (strcmp (fname, "_dl_runtime_resolve") == 0)
+ return ftrace_new_tailcall (bfun, mfun, fun);
+
+ return ftrace_new_return (bfun, mfun, fun);
+ }
case BTRACE_INSN_CALL:
/* Ignore calls to the next instruction. They are used for PIC. */