diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/btrace.c | 19 |
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. */ |