aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2018-09-24 11:33:11 +0200
committerMarkus Metzger <markus.t.metzger@intel.com>2018-10-10 12:27:55 +0200
commit2cb2ba9a5b7fe39f30604650efa64cff05cb72e4 (patch)
tree608403cbc959280149a7a5481ca43acff36213b1
parent673fe0f0a7a0624819f1b4cdc289f43691567e91 (diff)
downloadgdb-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/ChangeLog4
-rw-r--r--gdb/btrace.c14
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. */