btrace: check for indirect jump return in _Unwind_RaiseException
authorMarkus Metzger <markus.t.metzger@intel.com>
Mon, 24 Sep 2018 09:33:11 +0000 (11:33 +0200)
committerMarkus Metzger <markus.t.metzger@intel.com>
Wed, 10 Oct 2018 10:27:55 +0000 (12:27 +0200)
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
gdb/btrace.c

index f9e56be46da738f0653054253fef237c89f5ab50..dc355102abd7ada15d5869c356b0b8449872f998 100644 (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.
index e25f047ce243fd06b310e9dea0863a6da5e65441..d3ad0ab7de8813f873e6ae7a8ab4db4a7e625c1f 100644 (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.  */