This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch v4 07/24] record-btrace: optionally indent function call history
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Markus Metzger <markus dot t dot metzger at intel dot com>
- Cc: gdb-patches at sourceware dot org, Christian Himpel <christian dot himpel at intel dot com>
- Date: Sun, 18 Aug 2013 21:06:23 +0200
- Subject: Re: [patch v4 07/24] record-btrace: optionally indent function call history
- References: <1372842874-28951-1-git-send-email-markus dot t dot metzger at intel dot com> <1372842874-28951-8-git-send-email-markus dot t dot metzger at intel dot com>
On Wed, 03 Jul 2013 11:14:17 +0200, Markus Metzger wrote:
> Add a new modifier /c to the "record function-call-history" command to
> indent the function name based on its depth in the call stack.
>
> Also reorder the optional fields to have the indentation at the very beginning.
> Prefix the insn range (/i modifier) with "inst ".
> Prefix the source line (/l modifier) with "at ".
> Change the range syntax from "begin-end" to "begin,end" to allow copy&paste to
> the "record instruction-history" and "list" commands.
>
> Adjust the respective tests and add new tests for the /c modifier.
>
> There is one known bug regarding indentation that results from the fact that we
> have the current instruction already inside the branch trace. When the current
> instruction is the first (and only) instruction in a function on the outermost
> level for which we have not seen the call, the indentation starts at level 1
> with 2 leading spaces.
>
> Reviewed-by: Eli Zaretskii <eliz@gnu.org>
> CC: Christian Himpel <christian.himpel@intel.com>
> 2013-07-03 Markus Metzger <markus.t.metzger@intel.com>
>
> * record.h (enum record_print_flag)
> <record_print_indent_calls>: New.
> * record.c (get_call_history_modifiers): Recognize /c modifier.
> (_initialize_record): Document /c modifier.
> * record-btrace.c (btrace_call_history): Add btinfo parameter.
> Reorder fields. Optionally indent the function name. Update
> all users.
> * NEWS: Announce changes.
>
> testsuite/
> * gdb.btrace/function_call_history.exp: Fix expected field
> order for "record function-call-history".
> Add new tests for "record function-call-history /c".
> * gdb.btrace/exception.cc: New.
> * gdb.btrace/exception.exp: New.
> * gdb.btrace/tailcall.exp: New.
> * gdb.btrace/x86-tailcall.S: New.
> * gdb.btrace/x86-tailcall.c: New.
> * gdb.btrace/unknown_functions.c: New.
> * gdb.btrace/unknown_functions.exp: New.
> * gdb.btrace/Makefile.in (EXECUTABLES): Add new.
>
> doc/
> * gdb.texinfo (Process Record and Replay): Document new /c
> modifier accepted by "record function-call-history".
>
>
> ---
> gdb/NEWS | 6 +
> gdb/doc/gdb.texinfo | 12 +-
> gdb/record-btrace.c | 33 ++-
> gdb/record.c | 4 +
> gdb/record.h | 3 +
> gdb/testsuite/gdb.btrace/Makefile.in | 3 +-
> gdb/testsuite/gdb.btrace/exception.cc | 56 ++++
> gdb/testsuite/gdb.btrace/exception.exp | 65 +++++
> gdb/testsuite/gdb.btrace/function_call_history.exp | 112 +++++++--
> gdb/testsuite/gdb.btrace/tailcall.exp | 49 ++++
> gdb/testsuite/gdb.btrace/unknown_functions.c | 45 ++++
> gdb/testsuite/gdb.btrace/unknown_functions.exp | 58 +++++
> gdb/testsuite/gdb.btrace/x86-tailcall.S | 269 ++++++++++++++++++++
> gdb/testsuite/gdb.btrace/x86-tailcall.c | 39 +++
> 14 files changed, 716 insertions(+), 38 deletions(-)
> create mode 100644 gdb/testsuite/gdb.btrace/exception.cc
> create mode 100755 gdb/testsuite/gdb.btrace/exception.exp
> create mode 100644 gdb/testsuite/gdb.btrace/tailcall.exp
> create mode 100644 gdb/testsuite/gdb.btrace/unknown_functions.c
> create mode 100644 gdb/testsuite/gdb.btrace/unknown_functions.exp
> create mode 100644 gdb/testsuite/gdb.btrace/x86-tailcall.S
> create mode 100644 gdb/testsuite/gdb.btrace/x86-tailcall.c
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index e469f1e..6ac910a 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -13,6 +13,12 @@ Nios II ELF nios2*-*-elf
> Nios II GNU/Linux nios2*-*-linux
> Texas Instruments MSP430 msp430*-*-elf
>
> +* The command 'record function-call-history' supports a new modifier '/c' to
> + indent the function names based on their call stack depth.
> + The fields for the '/i' and '/l' modifier have been reordered.
> + The instruction range is now prefixed with 'insn'.
> + The source line range is now prefixed with 'at'.
> +
> * New commands:
> catch rethrow
> Like "catch throw", but catches a re-thrown exception.
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index fae54e4..2cfc20b 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -6419,7 +6419,9 @@ line for each sequence of instructions that belong to the same
> function giving the name of that function, the source lines
> for this instruction sequence (if the @code{/l} modifier is
> specified), and the instructions numbers that form the sequence (if
> -the @code{/i} modifier is specified).
> +the @code{/i} modifier is specified). The function names are indented
> +to reflect the call stack depth if the @code{/c} modifier is
> +specified.
>
> @smallexample
> (@value{GDBP}) @b{list 1, 10}
> @@ -6433,10 +6435,10 @@ the @code{/i} modifier is specified).
> 8 foo ();
> 9 ...
> 10 @}
> -(@value{GDBP}) @b{record function-call-history /l}
> -1 foo.c:6-8 bar
> -2 foo.c:2-3 foo
> -3 foo.c:9-10 bar
> +(@value{GDBP}) @b{record function-call-history /lc}
> +1 bar at foo.c:6,8
> +2 foo at foo.c:2,3
> +3 bar at foo.c:9,10
> @end smallexample
>
> By default, ten lines are printed. This can be changed using the
> diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
> index df69a41..99dc046 100644
> --- a/gdb/record-btrace.c
> +++ b/gdb/record-btrace.c
> @@ -435,7 +435,7 @@ btrace_call_history_insn_range (struct ui_out *uiout,
> end = begin + size - 1;
>
> ui_out_field_uint (uiout, "insn begin", begin);
> - ui_out_text (uiout, "-");
> + ui_out_text (uiout, ",");
> ui_out_field_uint (uiout, "insn end", end);
> }
>
> @@ -467,7 +467,7 @@ btrace_call_history_src_line (struct ui_out *uiout,
> if (end == begin)
> return;
>
> - ui_out_text (uiout, "-");
> + ui_out_text (uiout, ",");
> ui_out_field_int (uiout, "max line", end);
> }
>
> @@ -475,6 +475,7 @@ btrace_call_history_src_line (struct ui_out *uiout,
>
> static void
> btrace_call_history (struct ui_out *uiout,
> + const struct btrace_thread_info *btinfo,
> const struct btrace_call_iterator *begin,
> const struct btrace_call_iterator *end,
> enum record_print_flag flags)
> @@ -498,23 +499,33 @@ btrace_call_history (struct ui_out *uiout,
> ui_out_field_uint (uiout, "index", bfun->number);
> ui_out_text (uiout, "\t");
>
> + if ((flags & RECORD_PRINT_INDENT_CALLS) != 0)
> + {
> + int level = bfun->level + btinfo->level, i;
> +
> + for (i = 0; i < level; ++i)
> + ui_out_text (uiout, " ");
> + }
> +
> + if (sym != NULL)
> + ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (sym));
> + else if (msym != NULL)
> + ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (msym));
> + else
> + ui_out_field_string (uiout, "function", "<unknown>");
Here should be _("<unknown>"). (BTW I do not know about any existing
localized message catalogs for GDB.)
_() would be inappropriate for MI but in such case there should be IMO anyway
rather:
else if (!ui_out_is_mi_like_p (uiout))
ui_out_field_string (uiout, "function", _("<unknown>"));
But there is currently no MI interface setup for these commands (although you
have nicely prepared the commands for MI) so I do not find it worth the time
to discuss MI issues now.
> +
> if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
> {
> + ui_out_text (uiout, "\tinst ");
> btrace_call_history_insn_range (uiout, bfun);
> - ui_out_text (uiout, "\t");
> }
>
> if ((flags & RECORD_PRINT_SRC_LINE) != 0)
> {
> + ui_out_text (uiout, "\tat ");
> btrace_call_history_src_line (uiout, bfun);
> - ui_out_text (uiout, "\t");
> }
>
> - if (sym != NULL)
> - ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (sym));
> - else if (msym != NULL)
> - ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (msym));
> -
> ui_out_text (uiout, "\n");
> }
> }
> @@ -571,7 +582,7 @@ record_btrace_call_history (int size, int flags)
> }
>
> if (covered > 0)
> - btrace_call_history (uiout, &begin, &end, flags);
> + btrace_call_history (uiout, btinfo, &begin, &end, flags);
> else
> {
> if (size < 0)
> @@ -623,7 +634,7 @@ record_btrace_call_history_range (ULONGEST from, ULONGEST to, int flags)
> if (found == 0)
> btrace_call_end (&end, btinfo);
>
> - btrace_call_history (uiout, &begin, &end, flags);
> + btrace_call_history (uiout, btinfo, &begin, &end, flags);
> btrace_set_call_history (btinfo, &begin, &end);
>
> do_cleanups (uiout_cleanup);
> diff --git a/gdb/record.c b/gdb/record.c
> index 07b1b97..ffe9810 100644
> --- a/gdb/record.c
> +++ b/gdb/record.c
> @@ -575,6 +575,9 @@ get_call_history_modifiers (char **arg)
> case 'i':
> modifiers |= RECORD_PRINT_INSN_RANGE;
> break;
> + case 'c':
> + modifiers |= RECORD_PRINT_INDENT_CALLS;
> + break;
> default:
> error (_("Invalid modifier: %c."), *args);
> }
> @@ -809,6 +812,7 @@ function.\n\
> Without modifiers, it prints the function name.\n\
> With a /l modifier, the source file and line number range is included.\n\
> With a /i modifier, the instruction number range is included.\n\
> +With a /c modifier, the output is indented based on the call stack depth.\n\
> With no argument, prints ten more lines after the previous ten-line print.\n\
> \"record function-call-history -\" prints ten lines before a previous ten-line \
> print.\n\
> diff --git a/gdb/record.h b/gdb/record.h
> index 65d508f..9acc7de 100644
> --- a/gdb/record.h
> +++ b/gdb/record.h
> @@ -40,6 +40,9 @@ enum record_print_flag
>
> /* Print the instruction number range (if applicable). */
> RECORD_PRINT_INSN_RANGE = (1 << 1),
> +
> + /* Indent based on call stack depth (if applicable). */
> + RECORD_PRINT_INDENT_CALLS = (1 << 2)
> };
>
> /* Wrapper for target_read_memory that prints a debug message if
> diff --git a/gdb/testsuite/gdb.btrace/Makefile.in b/gdb/testsuite/gdb.btrace/Makefile.in
> index f4c06d1..5c70700 100644
> --- a/gdb/testsuite/gdb.btrace/Makefile.in
> +++ b/gdb/testsuite/gdb.btrace/Makefile.in
> @@ -1,7 +1,8 @@
> VPATH = @srcdir@
> srcdir = @srcdir@
>
> -EXECUTABLES = enable function_call_history instruction_history
> +EXECUTABLES = enable function_call_history instruction_history tailcall \
> + exception
>
> MISCELLANEOUS =
>
> diff --git a/gdb/testsuite/gdb.btrace/exception.cc b/gdb/testsuite/gdb.btrace/exception.cc
> new file mode 100644
> index 0000000..029a4bc
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/exception.cc
> @@ -0,0 +1,56 @@
> +/* 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/>. */
> +
> +static void
> +bad (void)
> +{
> + throw 42;
> +}
> +
> +static void
> +bar (void)
> +{
> + bad ();
> +}
> +
> +static void
> +foo (void)
> +{
> + bar ();
> +}
> +
> +static void
> +test (void)
> +{
> + try
> + {
> + foo ();
> + }
> + catch (...)
> + {
> + }
> +}
> +
> +int
> +main (void)
> +{
> + test ();
> + test (); /* bp.1 */
> + return 0; /* bp.2 */
> +}
> diff --git a/gdb/testsuite/gdb.btrace/exception.exp b/gdb/testsuite/gdb.btrace/exception.exp
> new file mode 100755
> index 0000000..77a07fd
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/exception.exp
> @@ -0,0 +1,65 @@
> +# 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 exception.cc
> +if [prepare_for_testing $testfile.exp $testfile $srcfile {c++ debug}] {
> + return -1
> +}
> +if ![runto_main] {
> + return -1
> +}
> +
> +# we want to see the full trace for this test
> +gdb_test_no_output "set record function-call-history-size 0"
> +
> +# set bp
> +set bp_1 [gdb_get_line_number "bp.1" $srcfile]
> +set bp_2 [gdb_get_line_number "bp.2" $srcfile]
> +gdb_breakpoint $bp_1
> +gdb_breakpoint $bp_2
> +
> +# trace the code between thw two breakpoints
> +gdb_continue_to_breakpoint "cont to $bp_1" ".*$srcfile:$bp_1.*"
gdb_continue_to_breakpoint "cont to bp_1" ".*$srcfile:$bp_1\r\n.*"
* Using line numbers in messages is not too great, the line numbers
occasionally change and it is causing needless gdb.sum differences.
Moreover the message does not say much etc.
* Original "$bp_1.*" can have false positive match (line 5 will match
incrorect line 50 etc.).
> +gdb_test_no_output "record btrace"
> +gdb_continue_to_breakpoint "cont to $bp_2" ".*$srcfile:$bp_2.*"
Likewise.
> +
> +# show the flat branch trace
> +send_gdb "record function-call-history 1\n"
> +gdb_expect_list "exception - flat" "\r\n$gdb_prompt $" {"\r
> +1\ttest\\(\\)\r
> +2\tfoo\\(\\)\r
> +3\tbar\\(\\)\r
> +4\tbad\\(\\)\r" "\r
> +\[0-9\]*\ttest\\(\\)"}
> +
> +# show the branch trace with calls indented
> +#
> +# here we see a known bug that the indentation starts at level 1 with
> +# two leading spaces instead of level 0 without leading spaces.
> +send_gdb "record function-call-history /c 1\n"
> +gdb_expect_list "exception - calls indented" "\r\n$gdb_prompt $" {"\r
> +1\t test\\(\\)\r
> +2\t foo\\(\\)\r
> +3\t bar\\(\\)\r
> +4\t bad\\(\\)\r" "\r
> +\[0-9\]*\t test\\(\\)"}
> diff --git a/gdb/testsuite/gdb.btrace/function_call_history.exp b/gdb/testsuite/gdb.btrace/function_call_history.exp
> index d694d5c..754cbbe 100644
> --- a/gdb/testsuite/gdb.btrace/function_call_history.exp
> +++ b/gdb/testsuite/gdb.btrace/function_call_history.exp
> @@ -62,6 +62,30 @@ gdb_test "record function-call-history" "
> 20\tinc\r
> 21\tmain\r" "record function-call-history - with size unlimited"
>
> +# show indented function call history with unlimited size
> +gdb_test "record function-call-history /c 1" "
> +1\tmain\r
> +2\t inc\r
> +3\tmain\r
> +4\t inc\r
> +5\tmain\r
> +6\t inc\r
> +7\tmain\r
> +8\t inc\r
> +9\tmain\r
> +10\t inc\r
> +11\tmain\r
> +12\t inc\r
> +13\tmain\r
> +14\t inc\r
> +15\tmain\r
> +16\t inc\r
> +17\tmain\r
> +18\t inc\r
> +19\tmain\r
> +20\t inc\r
> +21\tmain\r" "indented record function-call-history - with size unlimited"
> +
> # show function call history with size of 21, we expect to see all 21 entries
> gdb_test_no_output "set record function-call-history-size 21"
> # show function call history
> @@ -155,32 +179,35 @@ gdb_test "record function-call-history -" "At the start of the branch trace reco
> # make sure we cannot move any further back
> gdb_test "record function-call-history -" "At the start of the branch trace record\\." "record function-call-history - at the start (2)"
>
> +# don't mess around with path names
> +gdb_test_no_output "set filename-display basename"
> +
> # moving forward again, but this time with file and line number, expected to see the first 15 entries
> gdb_test "record function-call-history /l +" "
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r" "record function-call-history /l - show first 15 entries"
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r" "record function-call-history /l - show first 15 entries"
>
> # moving forward and expect to see the latest 6 entries
> gdb_test "record function-call-history /l +" "
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-41\tmain\r
> -.*$srcfile:22-24\tinc\r
> -.*$srcfile:40-43\tmain\r" "record function-call-history /l - show last 6 entries"
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,41\r
> +\[0-9\]*\tinc\tat $srcfile:22,24\r
> +\[0-9\]*\tmain\tat $srcfile:40,43\r" "record function-call-history /l - show last 6 entries"
>
> # moving further forward shouldn't work
> gdb_test "record function-call-history /l +" "At the end of the branch trace record\\." "record function-call-history /l - at the end (1)"
> @@ -219,3 +246,46 @@ gdb_test "record function-call-history" "
> 29\tfib\r
> 30\tfib\r
> 31\tmain" "show recursive function call history"
> +
> +# show indented function call history for fib
> +gdb_test "record function-call-history /c 21, +11" "
> +21\tmain\r
> +22\t fib\r
> +23\t fib\r
> +24\t fib\r
> +25\t fib\r
> +26\t fib\r
> +27\t fib\r
> +28\t fib\r
> +29\t fib\r
> +30\t fib\r
> +31\tmain" "indented record function-call-history - fib"
> +
> +# make sure we can handle incomplete trace with respect to indentation
> +if ![runto_main] {
> + return -1
> +}
> +# navigate to the fib in line 24 above
> +gdb_breakpoint fib
> +gdb_continue_to_breakpoint "cont to fib.1"
> +gdb_continue_to_breakpoint "cont to fib.2"
> +gdb_continue_to_breakpoint "cont to fib.3"
> +gdb_continue_to_breakpoint "cont to fib.4"
> +
> +# start tracing
> +gdb_test_no_output "record btrace"
> +
> +# continue until line 30 above
> +delete_breakpoints
> +set bp_location [gdb_get_line_number "bp.2" $testfile.c]
> +gdb_breakpoint $bp_location
> +gdb_continue_to_breakpoint "cont to $bp_location" ".*$testfile.c:$bp_location.*"
Like above.
> +
> +# let's look at the trace. we expect to see the tail of the above listing.
> +gdb_test "record function-call-history /c" "
> +1\t fib\r
> +2\t fib\r
> +3\t fib\r
> +4\t fib\r
> +5\t fib\r
> +6\tmain" "indented record function-call-history - fib"
> diff --git a/gdb/testsuite/gdb.btrace/tailcall.exp b/gdb/testsuite/gdb.btrace/tailcall.exp
> new file mode 100644
> index 0000000..cf9fdf3
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/tailcall.exp
> @@ -0,0 +1,49 @@
> +# 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 x86-tailcall.S
> +if [prepare_for_testing tailcall.exp $testfile $srcfile {c++ debug}] {
> + return -1
> +}
This does not work for example on i386 host or on x86_64 host with:
$ runtest CXX_FOR_TARGET="g++ -m32" gdb.btrace/tailcall.exp
Running ./gdb.btrace/tailcall.exp ...
gdb compile failed, x86-tailcall.c: Assembler messages:
x86-tailcall.c:100: Error: cannot represent relocation type BFD_RELOC_64
...
You can look for example at gdb.arch/amd64-tailcall-noret.exp for:
* how to skip the testcase if the target is not 64-bit x86_64.
* (optional) how to provide COMPILE=1 convenience parameter for debugging to
run the testcase from .c file with local compiler (sure nobody guarantees
your compiler will produce compatible .s for the testcase but still I find
it sometimes handy).
> +if ![runto_main] {
> + return -1
> +}
> +
> +# we want to see the full trace for this test
> +gdb_test_no_output "set record function-call-history-size 0"
> +
> +# trace the call to foo
> +gdb_test_no_output "record btrace"
> +gdb_test "next"
> +
> +# show the flat branch trace
> +gdb_test "record function-call-history 1" "
> +1\tfoo\r
> +2\tbar\r
> +3\tmain" "tailcall - flat"
> +
> +# show the branch trace with calls indented
> +gdb_test "record function-call-history /c 1" "
> +1\t foo\r
> +2\t bar\r
> +3\tmain" "tailcall - calls indented"
> diff --git a/gdb/testsuite/gdb.btrace/unknown_functions.c b/gdb/testsuite/gdb.btrace/unknown_functions.c
> new file mode 100644
> index 0000000..178c3e9
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/unknown_functions.c
> @@ -0,0 +1,45 @@
> +/* 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/>. */
> +
> +static int foo (void);
> +
> +int test (void)
> +{
> + return foo ();
> +}
> +
> +static int
> +bar (void)
> +{
> + return 42;
> +}
> +
> +static int
> +foo (void)
> +{
> + return bar ();
> +}
> +
> +int
> +main (void)
> +{
> + test ();
> + test ();
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.btrace/unknown_functions.exp b/gdb/testsuite/gdb.btrace/unknown_functions.exp
> new file mode 100644
> index 0000000..c7f33bf
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/unknown_functions.exp
> @@ -0,0 +1,58 @@
> +# 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
> +
> +# discard local symbols
> +set ldflags "additional_flags=-Wl,-x"
> +if [prepare_for_testing $testfile.exp $testfile $srcfile $ldflags] {
> + return -1
> +}
> +if ![runto test] {
> + return -1
> +}
> +
> +# we want to see the full trace for this test
> +gdb_test_no_output "set record function-call-history-size 0"
> +
> +# trace from one call of test to the next
> +gdb_test_no_output "record btrace"
> +gdb_continue_to_breakpoint "cont to test" ".*test.*"
> +
> +# show the flat branch trace
> +gdb_test "record function-call-history 1" "
> +1\t<unknown>\r
> +2\t<unknown>\r
> +3\t<unknown>\r
> +4\ttest\r
> +5\tmain\r
> +6\ttest" "unknown - flat"
> +
> +# show the branch trace with calls indented
> +gdb_test "record function-call-history /c 1" "
> +1\t <unknown>\r
> +2\t <unknown>\r
> +3\t <unknown>\r
> +4\t test\r
> +5\tmain\r
> +6\t test" "unknown - calls indented"
> diff --git a/gdb/testsuite/gdb.btrace/x86-tailcall.S b/gdb/testsuite/gdb.btrace/x86-tailcall.S
> new file mode 100644
> index 0000000..5a4fede
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/x86-tailcall.S
> @@ -0,0 +1,269 @@
> +/* 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/>.
> +
> +
> + This file has been generated using:
> + gcc -S -O2 -g x86-tailcall.c -o x86-tailcall.S */
It is better to use also -dA if one needs to deal with the .S source.
> +
> + .file "x86-tailcall.c"
> + .section .debug_abbrev,"",@progbits
> +.Ldebug_abbrev0:
[...]
> + .section .debug_str,"MS",@progbits,1
> +.LASF1:
> + .string "gdb/testsuite/gdb.btrace/x86-tailcall.c"
> +.LASF4:
> + .string "answer"
> +.LASF0:
> + .string "GNU C 4.4.4 20100726 (Red Hat 4.4.4-13)"
> +.LASF3:
> + .string "main"
> +.LASF2:
> + .string "/users/mmetzger/gdb/gerrit/git"
You could replace the directory for example by (that is IIRC not correct
anyway for out-of-src-tree builds but it at least finds the source for
in-src-tree builds)::
.string ""
> + .ident "GCC: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)"
> + .section .note.GNU-stack,"",@progbits
> diff --git a/gdb/testsuite/gdb.btrace/x86-tailcall.c b/gdb/testsuite/gdb.btrace/x86-tailcall.c
> new file mode 100644
> index 0000000..9e3b183
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/x86-tailcall.c
> @@ -0,0 +1,39 @@
> +/* 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/>. */
> +
> +static __attribute__ ((noinline)) int
> +bar (void)
> +{
> + return 42;
> +}
> +
> +static __attribute__ ((noinline)) int
> +foo (void)
> +{
> + return bar ();
> +}
> +
> +int
> +main (void)
> +{
> + int answer;
> +
> + answer = foo ();
> + return ++answer;
> +}
> --
> 1.7.1