btrace: check for indirect jump return in _Unwind_RaiseException

Some versions of _Unwind_RaiseException, e.g. on Fedora 28, use an
indirect jump to return to the exception handler.

This messes up the output of "record function-call-history /c" since the
return is interpreted as cross-function goto.  It had been detected by
gdb.btrace/exception.exp.

Add a heuristic for "_Unwind_*" functions to interpret an indirect jump
that ends in one of our caller functions as return to the first instance
of that function in our call stack.

gdb/
	* btrace.c (ftrace_update_function): Add indirect jump heuristic.
This commit is contained in:
Markus Metzger 2018-09-24 11:33:11 +02:00
parent 673fe0f0a7
commit 2cb2ba9a5b
2 changed files with 18 additions and 0 deletions

View file

@ -1,3 +1,7 @@
2018-10-10 Markus Metzger <markus.t.metzger@intel.com>
* btrace.c (ftrace_update_function): Add indirect jump heuristic.
2018-10-09 Tom Tromey <tom@tromey.com>
* configure: Rebuild.

View file

@ -620,6 +620,20 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
if (start == pc)
return ftrace_new_tailcall (btinfo, mfun, fun);
/* Some versions of _Unwind_RaiseException use an indirect
jump to 'return' to the exception handler of the caller
handling the exception instead of a return. Let's restrict
this heuristic to that and related functions. */
const char *fname = ftrace_print_function_name (bfun);
if (strncmp (fname, "_Unwind_", strlen ("_Unwind_")) == 0)
{
struct btrace_function *caller
= ftrace_find_call_by_number (btinfo, bfun->up);
caller = ftrace_find_caller (btinfo, caller, mfun, fun);
if (caller != NULL)
return ftrace_new_return (btinfo, 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 we're switching functions
and as an intra-function branch if we don't. */