From 2cb2ba9a5b7fe39f30604650efa64cff05cb72e4 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Mon, 24 Sep 2018 11:33:11 +0200 Subject: [PATCH] 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. --- gdb/ChangeLog | 4 ++++ gdb/btrace.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f9e56be..dc35510 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2018-10-10 Markus Metzger + + * btrace.c (ftrace_update_function): Add indirect jump heuristic. + 2018-10-09 Tom Tromey * configure: Rebuild. diff --git a/gdb/btrace.c b/gdb/btrace.c index e25f047..d3ad0ab 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -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. */ -- 2.7.4