Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Markus Metzger <markus.t.metzger@intel.com>
To: jan.kratochvil@redhat.com
Cc: gdb-patches@sourceware.org
Subject: [patch v4 24/24] record-btrace: skip tail calls in back trace
Date: Wed, 03 Jul 2013 09:14:00 -0000	[thread overview]
Message-ID: <1372842874-28951-25-git-send-email-markus.t.metzger@intel.com> (raw)
In-Reply-To: <1372842874-28951-1-git-send-email-markus.t.metzger@intel.com>

The branch trace represents the caller/callee relationship of tail calls.  The
caller of a tail call is shown in the back trace and in the function-call
history.

This is not consistent with GDB's normal behavior, where the tail caller is not
shown in the back trace.
It further causes the finish command to fail for tail calls.

This patch skips tail calls when computing the back trace during replay.  The
finish command now works also for tail calls.

The tail caller is still shown in the function-call history.

I'm not sure which is the better behavior.  I liked seeing the tail caller in
the call stack and I'm not using the finish command very often.  On the other
hand, reverse/replay should be as close to live debugging as possible.

2013-07-03  Markus Metzger  <markus.t.metzger@intel.com>

	* record-btrace.c (record_btrace_frame_sniffer): Skip tail calls.

testsuite/
	* gdb.btrace/tailcall.exp: Update.  Add stepping tests.
	* gdb.btrace/rn-dl-bind.c: New.
	* gdb.btrace/rn-dl-bind.exp: New.


---
 gdb/record-btrace.c                     |   15 ++++++----
 gdb/testsuite/gdb.btrace/rn-dl-bind.c   |   37 +++++++++++++++++++++++
 gdb/testsuite/gdb.btrace/rn-dl-bind.exp |   48 +++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.btrace/tailcall.exp   |   25 +++++++++++++--
 4 files changed, 115 insertions(+), 10 deletions(-)
 create mode 100644 gdb/testsuite/gdb.btrace/rn-dl-bind.c
 create mode 100644 gdb/testsuite/gdb.btrace/rn-dl-bind.exp

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index b45a5fb..9feda30 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1026,7 +1026,7 @@ record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
   cache = *this_cache;
 
   stack = 0;
-  code = get_frame_func (this_frame);
+  code = cache->pc;
   special = (CORE_ADDR) cache->bfun;
 
   *this_id = frame_id_build_special (stack, code, special);
@@ -1120,6 +1120,13 @@ record_btrace_frame_sniffer (const struct frame_unwind *self,
   caller = bfun->up;
   pc = 0;
 
+  /* Skip tail calls.  */
+  while (caller != NULL && (bfun->flags & BFUN_UP_LINKS_TO_TAILCALL) != 0)
+    {
+      bfun = caller;
+      caller = bfun->up;
+    }
+
   /* Determine where to find the PC in the upper function segment.  */
   if (caller != NULL)
     {
@@ -1133,11 +1140,7 @@ record_btrace_frame_sniffer (const struct frame_unwind *self,
 	  insn = VEC_last (btrace_insn_s, caller->insn);
 	  pc = insn->pc;
 
-	  /* We link directly to the jump instruction in the case of a tail
-	     call, since the next instruction will likely be outside of the
-	     caller function.  */
-	  if ((bfun->flags & BFUN_UP_LINKS_TO_TAILCALL) == 0)
-	    pc += gdb_insn_length (get_frame_arch (this_frame), pc);
+	  pc += gdb_insn_length (get_frame_arch (this_frame), pc);
 	}
 
       DEBUG ("[frame] sniffed frame for %s on level %d",
diff --git a/gdb/testsuite/gdb.btrace/rn-dl-bind.c b/gdb/testsuite/gdb.btrace/rn-dl-bind.c
new file mode 100644
index 0000000..4930297
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/rn-dl-bind.c
@@ -0,0 +1,37 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+int test (void)
+{
+  int ret;
+
+  ret = strtoul ("42", NULL, 10);	/* test.1 */
+  return ret;				/* test.2 */
+}					/* test.3 */
+
+int
+main (void)
+{
+  int ret;
+
+  ret = test ();			/* main.1 */
+  return ret;				/* main.2 */
+}					/* main.3 */
diff --git a/gdb/testsuite/gdb.btrace/rn-dl-bind.exp b/gdb/testsuite/gdb.btrace/rn-dl-bind.exp
new file mode 100644
index 0000000..4d803f9
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/rn-dl-bind.exp
@@ -0,0 +1,48 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start inferior
+standard_testfile
+if [prepare_for_testing $testfile.exp $testfile $srcfile {c++ debug}] {
+    return -1
+}
+if ![runto_main] {
+    return -1
+}
+
+# trace the code for the call to test
+gdb_test_no_output "record btrace" "rn-dl-bind, 0.1"
+gdb_test "next" ".*main\.2.*" "rn-dl-bind, 0.2"
+
+# just dump the function-call-history to help debugging
+gdb_test_no_output "set record function-call-history-size 0" "rn-dl-bind, 0.3"
+gdb_test "record function-call-history /cli 1" ".*" "rn-dl-bind, 0.4"
+
+# check that we can reverse-next and next
+gdb_test "reverse-next" ".*main\.1.*" "rn-dl-bind, 1.1"
+gdb_test "next" ".*main\.2.*" "rn-dl-bind, 1.2"
+
+# now go into test and try to reverse-next and next over the library call
+gdb_test "reverse-step" ".*test\.3.*" "rn-dl-bind, 2.1"
+gdb_test "reverse-step" ".*test\.2.*" "rn-dl-bind, 2.2"
+gdb_test "reverse-next" ".*test\.1.*" "rn-dl-bind, 2.3"
+gdb_test "next" ".*test\.2.*" "rn-dl-bind, 2.4"
diff --git a/gdb/testsuite/gdb.btrace/tailcall.exp b/gdb/testsuite/gdb.btrace/tailcall.exp
index 5cadee0..df8d66a 100644
--- a/gdb/testsuite/gdb.btrace/tailcall.exp
+++ b/gdb/testsuite/gdb.btrace/tailcall.exp
@@ -57,12 +57,29 @@ gdb_test "record goto 4" "
 # check the backtrace
 gdb_test "backtrace" "
 #0.*bar.*at .*x86-tailcall.c:24.*\r
-#1.*foo.*at .*x86-tailcall.c:29.*\r
-#2.*main.*at .*x86-tailcall.c:37.*\r
+#1.*main.*at .*x86-tailcall.c:37.*\r
 Backtrace stopped: not enough registers or memory available to unwind further" "backtrace in bar"
 
 # walk the backtrace
 gdb_test "up" "
-.*foo \\(\\) at .*x86-tailcall.c:29.*" "up to foo"
-gdb_test "up" "
 .*main \\(\\) at .*x86-tailcall.c:37.*" "up to main"
+gdb_test "down" "
+#0.*bar.*at .*x86-tailcall.c:24.*" "down to bar"
+
+# test stepping into and out of tailcalls.
+gdb_test "finish" "
+.*main.*at .*x86-tailcall.c:37.*" "step, 1.1"
+gdb_test "reverse-step" "
+.*bar.*at .*x86-tailcall.c:24.*" "step, 1.2"
+gdb_test "reverse-finish" "
+.*foo \\(\\) at .*x86-tailcall.c:29.*" "step, 1.3"
+gdb_test "reverse-step" "
+.*main.*at .*x86-tailcall.c:37.*" "step, 1.4"
+gdb_test "next" "
+.*main.*at .*x86-tailcall.c:39.*" "step, 1.5"
+gdb_test "reverse-next" "
+.*main.*at .*x86-tailcall.c:37.*" "step, 1.6"
+gdb_test "step" "
+.*foo \\(\\) at .*x86-tailcall.c:29.*" "step, 1.7"
+gdb_test "finish" "
+.*main.*at .*x86-tailcall.c:37.*" "step, 1.8"
-- 
1.7.1


  parent reply	other threads:[~2013-07-03  9:14 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-03  9:15 [patch v4 00/24] record-btrace: reverse Markus Metzger
2013-07-03  9:14 ` [patch v4 10/24] target: add ops parameter to to_prepare_to_store method Markus Metzger
2013-08-18 19:07   ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 19/24] btrace, linux: fix memory leak when reading branch trace Markus Metzger
2013-08-18 19:09   ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 03/24] btrace: change branch trace data structure Markus Metzger
2013-08-18 19:05   ` Jan Kratochvil
2013-09-10  9:11     ` Metzger, Markus T
2013-09-12 20:09       ` Jan Kratochvil
2013-09-16  9:01         ` Metzger, Markus T
2013-09-21 19:44           ` Jan Kratochvil
2013-09-23  6:54             ` Metzger, Markus T
2013-09-23  7:15               ` Jan Kratochvil
2013-09-23  7:27                 ` Metzger, Markus T
2013-09-22 16:57         ` Jan Kratochvil
2013-09-22 17:16           ` Jan Kratochvil
2013-07-03  9:14 ` Markus Metzger [this message]
2013-08-18 19:10   ` [patch v4 24/24] record-btrace: skip tail calls in back trace Jan Kratochvil
2013-09-17 14:28     ` Metzger, Markus T
2013-09-18  8:28       ` Metzger, Markus T
2013-09-18  9:52         ` Metzger, Markus T
2013-07-03  9:14 ` [patch v4 20/24] btrace, gdbserver: read branch trace incrementally Markus Metzger
2013-08-18 19:09   ` Jan Kratochvil
2013-09-16 12:48     ` Metzger, Markus T
2013-09-22 14:42       ` Jan Kratochvil
2013-09-23  7:09         ` Metzger, Markus T
2013-09-25 19:05           ` Jan Kratochvil
2013-09-26  6:27             ` Metzger, Markus T
2013-07-03  9:14 ` [patch v4 11/24] record-btrace: supply register target methods Markus Metzger
2013-08-18 19:07   ` Jan Kratochvil
2013-09-16  9:19     ` Metzger, Markus T
2013-09-22 13:55       ` Jan Kratochvil
2013-09-23  6:55         ` Metzger, Markus T
2013-07-03  9:14 ` [patch v4 16/24] record-btrace: provide target_find_new_threads method Markus Metzger
2013-08-18 19:15   ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 08/24] record-btrace: make ranges include begin and end Markus Metzger
2013-08-18 19:12   ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 07/24] record-btrace: optionally indent function call history Markus Metzger
2013-08-18 19:06   ` Jan Kratochvil
2013-09-10 13:06     ` Metzger, Markus T
2013-09-10 13:08       ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 22/24] infrun: reverse stepping from unknown functions Markus Metzger
2013-08-18 19:09   ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 14/24] record-btrace: provide xfer_partial target method Markus Metzger
2013-08-18 19:08   ` Jan Kratochvil
2013-09-16  9:30     ` Metzger, Markus T
2013-09-22 14:18       ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 02/24] record: upcase record_print_flag enumeration constants Markus Metzger
2013-08-18 19:11   ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 05/24] record-btrace: start counting at one Markus Metzger
2013-08-18 19:11   ` Jan Kratochvil
2013-07-03  9:14 ` [patch v4 09/24] btrace: add replay position to btrace thread info Markus Metzger
2013-08-18 19:07   ` Jan Kratochvil
2013-09-10 13:24     ` Metzger, Markus T
2013-09-12 20:19       ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 18/24] record-btrace: extend unwinder Markus Metzger
2013-08-18 19:08   ` Jan Kratochvil
2013-09-16 11:21     ` Metzger, Markus T
2013-09-27 13:55       ` Jan Kratochvil
2013-09-30  9:45         ` Metzger, Markus T
2013-09-30 10:26           ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 04/24] record-btrace: fix insn range in function call history Markus Metzger
2013-08-18 19:06   ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 21/24] record-btrace: show trace from enable location Markus Metzger
2013-08-18 19:10   ` instruction_history.exp unset variable [Re: [patch v4 21/24] record-btrace: show trace from enable location] Jan Kratochvil
2013-09-16 14:11     ` Metzger, Markus T
2013-08-18 19:16   ` [patch v4 21/24] record-btrace: show trace from enable location Jan Kratochvil
2013-07-03  9:15 ` [patch v4 12/24] frame, backtrace: allow targets to supply a frame unwinder Markus Metzger
2013-08-18 19:14   ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 01/24] gdbarch: add instruction predicate methods Markus Metzger
2013-07-03  9:49   ` Mark Kettenis
2013-07-03 11:10     ` Metzger, Markus T
2013-08-18 19:04   ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 06/24] btrace: increase buffer size Markus Metzger
2013-08-18 19:06   ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 23/24] record-btrace: add (reverse-)stepping support Markus Metzger
2013-08-18 19:09   ` Jan Kratochvil
2013-09-17  9:43     ` Metzger, Markus T
2013-09-29 17:24       ` Jan Kratochvil
2013-09-30  9:30         ` Metzger, Markus T
2013-09-30 10:25           ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 15/24] record-btrace: add to_wait and to_resume target methods Markus Metzger
2013-08-18 19:08   ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 17/24] record-btrace: add record goto " Markus Metzger
2013-08-18 19:08   ` Jan Kratochvil
2013-07-03  9:15 ` [patch v4 13/24] record-btrace, frame: supply target-specific unwinder Markus Metzger
2013-08-18 19:07   ` Jan Kratochvil
2013-08-18 19:04 ` [patch v4 00/24] record-btrace: reverse Jan Kratochvil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1372842874-28951-25-git-send-email-markus.t.metzger@intel.com \
    --to=markus.t.metzger@intel.com \
    --cc=gdb-patches@sourceware.org \
    --cc=jan.kratochvil@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox