diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2018-09-24 11:33:11 +0200 |
---|---|---|
committer | Markus Metzger <markus.t.metzger@intel.com> | 2018-10-10 12:27:55 +0200 |
commit | 2cb2ba9a5b7fe39f30604650efa64cff05cb72e4 (patch) | |
tree | 608403cbc959280149a7a5481ca43acff36213b1 | |
parent | 673fe0f0a7a0624819f1b4cdc289f43691567e91 (diff) | |
download | gdb-2cb2ba9a5b7fe39f30604650efa64cff05cb72e4.zip gdb-2cb2ba9a5b7fe39f30604650efa64cff05cb72e4.tar.gz gdb-2cb2ba9a5b7fe39f30604650efa64cff05cb72e4.tar.bz2 |
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.
-rw-r--r-- | gdb/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/btrace.c | 14 |
2 files changed, 18 insertions, 0 deletions
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 <markus.t.metzger@intel.com> + + * btrace.c (ftrace_update_function): Add indirect jump heuristic. + 2018-10-09 Tom Tromey <tom@tromey.com> * 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. */ |