diff options
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/NEWS | 8 | ||||
-rw-r--r-- | gdb/btrace.c | 15 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 13 | ||||
-rw-r--r-- | gdb/record-btrace.c | 33 | ||||
-rw-r--r-- | gdb/record.c | 4 | ||||
-rw-r--r-- | gdb/record.h | 3 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 14 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/exception.cc | 56 | ||||
-rwxr-xr-x | gdb/testsuite/gdb.btrace/exception.exp | 68 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/function_call_history.exp | 92 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/tailcall.exp | 62 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/unknown_functions.c | 45 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/unknown_functions.exp | 60 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/x86-tailcall.S | 279 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/x86-tailcall.c | 39 |
18 files changed, 771 insertions, 40 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 50c6bcd..b67e66b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2014-01-16 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. + +2014-01-16 Markus Metzger <markus.t.metzger@intel.com> + * common/linux-btrace.c (linux_enable_btrace): Enlarge buffer. 2014-01-16 Markus Metzger <markus.t.metzger@intel.com> @@ -7,6 +7,14 @@ at one. This also affects the instruction ranges reported by the 'record function-call-history' command when given the /i modifier. +* 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 source line range is now prefixed with 'at'. + The instruction range is now prefixed with 'inst'. + Both ranges are now printed as '<from>, <to>' to allow copy&paste to the + "record instruction-history" and "list" commands. + *** Changes in GDB 7.7 * Improved support for process record-replay and reverse debugging on diff --git a/gdb/btrace.c b/gdb/btrace.c index 2e9e008..1d060d3e 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -630,8 +630,10 @@ btrace_compute_ftrace (struct btrace_thread_info *btinfo, if (begin == NULL) begin = end; - /* Maintain the function level offset. */ - level = min (level, end->level); + /* Maintain the function level offset. + For all but the last block, we do it here. */ + if (blk != 0) + level = min (level, end->level); ftrace_update_insns (end, pc); ftrace_update_lines (end, pc); @@ -651,6 +653,15 @@ btrace_compute_ftrace (struct btrace_thread_info *btinfo, } pc += size; + + /* Maintain the function level offset. + For the last block, we do it here to not consider the last + instruction. + Since the last instruction corresponds to the current instruction + and is not really part of the execution history, it shouldn't + affect the level. */ + if (blk == 0) + level = min (level, end->level); } } diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 9ec5fd4..f28610b 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2014-01-16 Markus Metzger <markus.t.metzger@intel.com> + + * gdb.texinfo (Process Record and Replay): Document new /c + modifier accepted by "record function-call-history". + Add /i modifier to "record function-call-history" example. + 2014-01-15 Yuanhui Zhang <asmwarrior@gmail.com> Joel Brobecker <brobecker@adacore.com> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 94e8d48..51f1c41 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -6490,7 +6490,10 @@ 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. The @code{/l}, @code{/i}, and @code{/c} modifiers can be +given together. @smallexample (@value{GDBP}) @b{list 1, 10} @@ -6504,10 +6507,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 /ilc} +1 bar inst 1,4 at foo.c:6,8 +2 foo inst 5,10 at foo.c:2,3 +3 bar inst 11,13 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 97d38fc..c53acec 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -433,7 +433,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); } @@ -465,7 +465,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); } @@ -473,6 +473,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) @@ -496,23 +497,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 if (!ui_out_is_mi_like_p (uiout)) + ui_out_field_string (uiout, "function", "??"); + 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"); } } @@ -569,7 +580,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) @@ -621,7 +632,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 f2cfcc8..4c67192 100644 --- a/gdb/record.c +++ b/gdb/record.c @@ -586,6 +586,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); } @@ -820,6 +823,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 962e382..17d1772 100644 --- a/gdb/record.h +++ b/gdb/record.h @@ -38,6 +38,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/ChangeLog b/gdb/testsuite/ChangeLog index 390b951..f1fd8a1 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,19 @@ 2014-01-16 Markus Metzger <markus.t.metzger@intel.com> + * 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. + +2014-01-16 Markus Metzger <markus.t.metzger@intel.com> + * gdb.btrace/instruction_history.exp: Update. * gdb.btrace/function_call_history.exp: Update. diff --git a/gdb/testsuite/gdb.btrace/Makefile.in b/gdb/testsuite/gdb.btrace/Makefile.in index f4c06d1..606de6e 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 unknown_functions 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..46ed542 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/exception.exp @@ -0,0 +1,68 @@ +# 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 the two breakpoints +gdb_continue_to_breakpoint "cont to bp.1" ".*$srcfile:$bp_1\r\n.*" +gdb_test_no_output "record btrace" +gdb_continue_to_breakpoint "cont to bp.2" ".*$srcfile:$bp_2\r\n.*" + +# show the flat branch trace +send_gdb "record function-call-history 1\n" +gdb_expect_list "flat" "\r\n$gdb_prompt $" [list \ + [join [list \ + "1\ttest\\(\\)" \ + "2\tfoo\\(\\)" \ + "3\tbar\\(\\)" \ + "4\tbad\\(\\)" \ + ] "\r\n"] \ + "" \ + "\[0-9\]*\ttest\\(\\)"] + +# show the branch trace with calls indented +send_gdb "record function-call-history /c 1\n" +gdb_expect_list "indented" "\r\n$gdb_prompt $" [list \ + [join [list \ + "1\ttest\\(\\)" \ + "2\t foo\\(\\)" \ + "3\t bar\\(\\)" \ + "4\t bad\\(\\)\r" \ + ] "\r\n"] \ + "" \ + "\[0-9\]*\ttest\\(\\)"] diff --git a/gdb/testsuite/gdb.btrace/function_call_history.exp b/gdb/testsuite/gdb.btrace/function_call_history.exp index cd94dec..f7a9233 100644 --- a/gdb/testsuite/gdb.btrace/function_call_history.exp +++ b/gdb/testsuite/gdb.btrace/function_call_history.exp @@ -137,32 +137,37 @@ 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\\." "backward - 4" +# 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 +" [join [list \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain"] "\r\n"] "forward /l - 1" + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + ] "\r\n"] "forward /l - 1" # moving forward and expect to see the latest 6 entries gdb_test "record function-call-history /l +" [join [list \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-41\tmain" \ - ".*$srcfile:22-24\tinc" \ - ".*$srcfile:40-43\tmain"] "\r\n"] "forward /l - 2" + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,41" \ + "\[0-9\]*\tinc\tat $srcfile:22,24" \ + "\[0-9\]*\tmain\tat $srcfile:40,43" \ + ] "\r\n"] "forward /l - 2" # moving further forward shouldn't work gdb_test "record function-call-history /l +" "At the end of the branch trace record\\." "forward /l - 3" @@ -202,3 +207,48 @@ gdb_test "record function-call-history" [join [list \ "29\tfib" \ "30\tfib" \ "31\tmain"] "\r\n"] "recursive" + +# show indented function call history for fib +gdb_test "record function-call-history /c 21, +11" [join [list \ + "21\tmain" \ + "22\t fib" \ + "23\t fib" \ + "24\t fib" \ + "25\t fib" \ + "26\t fib" \ + "27\t fib" \ + "28\t fib" \ + "29\t fib" \ + "30\t fib" \ + "31\tmain" \ + ] "\r\n"] "indented" + +# 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.2" ".*$testfile.c:$bp_location\r\n.*" + +# let's look at the trace. we expect to see the tail of the above listing. +gdb_test "record function-call-history /c" [join [list \ + "1\t fib" \ + "2\t fib" \ + "3\t fib" \ + "4\t fib" \ + "5\t fib" \ + "6\tmain" \ + ] "\r\n"] "indented tail" diff --git a/gdb/testsuite/gdb.btrace/tailcall.exp b/gdb/testsuite/gdb.btrace/tailcall.exp new file mode 100644 index 0000000..c965675 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/tailcall.exp @@ -0,0 +1,62 @@ +# 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 + +set opts {} +if [info exists COMPILE] { + # make check RUNTESTFLAGS="gdb.btrace/tailcall.exp COMPILE=1" + standard_testfile x86-tailcall.c + lappend opts debug optimize=-O2 +} elseif { ![istarget x86_64-*-* ] || ![is_lp64_target] } { + verbose "Skipping ${testfile}." + return +} + +if [prepare_for_testing tailcall.exp $testfile $srcfile $opts] { + 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" + +# 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" [join [list \ + "1\tfoo" \ + "2\tbar" \ + "3\tmain" \ + ] "\r\n"] "flat" + +# show the branch trace with calls indented +gdb_test "record function-call-history /c 1" [join [list \ + "1\t foo" \ + "2\t bar" \ + "3\tmain" \ + ] "\r\n"] "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..f678358 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/unknown_functions.exp @@ -0,0 +1,60 @@ +# 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" [join [list \ + "1\t\\\?\\\?" \ + "2\t\\\?\\\?" \ + "3\t\\\?\\\?" \ + "4\ttest" \ + "5\tmain" \ + "6\ttest" \ + ] "\r\n"] "flat" + +# show the branch trace with calls indented +gdb_test "record function-call-history /c 1" [join [list \ + "1\t \\\?\\\?" \ + "2\t \\\?\\\?" \ + "3\t \\\?\\\?" \ + "4\t test" \ + "5\tmain" \ + "6\t test" \ + ] "\r\n"] "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..edf9a3b --- /dev/null +++ b/gdb/testsuite/gdb.btrace/x86-tailcall.S @@ -0,0 +1,279 @@ +/* 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 -dA -g x86-tailcall.c -o x86-tailcall.S */ + + .file "x86-tailcall.c" + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .section .debug_line,"",@progbits +.Ldebug_line0: + .text +.Ltext0: + .p2align 4,,15 + .type bar, @function +bar: +.LFB0: + .file 1 "x86-tailcall.c" + # x86-tailcall.c:22 + .loc 1 22 0 + .cfi_startproc + # basic block 2 + # x86-tailcall.c:24 + .loc 1 24 0 + movl $42, %eax + ret + .cfi_endproc +.LFE0: + .size bar, .-bar + .p2align 4,,15 + .type foo, @function +foo: +.LFB1: + # x86-tailcall.c:28 + .loc 1 28 0 + .cfi_startproc + # basic block 2 + # x86-tailcall.c:29 + .loc 1 29 0 + jmp bar + .cfi_endproc +.LFE1: + .size foo, .-foo + .p2align 4,,15 +.globl main + .type main, @function +main: +.LFB2: + # x86-tailcall.c:34 + .loc 1 34 0 + .cfi_startproc + # basic block 2 + # x86-tailcall.c:37 + .loc 1 37 0 + call foo +.LVL0: + addl $1, %eax +.LVL1: + # x86-tailcall.c:39 + .loc 1 39 0 + ret + .cfi_endproc +.LFE2: + .size main, .-main +.Letext0: + .section .debug_loc,"",@progbits +.Ldebug_loc0: +.LLST0: + .quad .LVL0-.Ltext0 # Location list begin address (*.LLST0) + .quad .LVL1-.Ltext0 # Location list end address (*.LLST0) + .value 0x3 # Location expression size + .byte 0x70 # DW_OP_breg0 + .sleb128 1 + .byte 0x9f # DW_OP_stack_value + .quad .LVL1-.Ltext0 # Location list begin address (*.LLST0) + .quad .LFE2-.Ltext0 # Location list end address (*.LLST0) + .value 0x1 # Location expression size + .byte 0x50 # DW_OP_reg0 + .quad 0x0 # Location list terminator begin (*.LLST0) + .quad 0x0 # Location list terminator end (*.LLST0) + .section .debug_info + .long 0x9c # Length of Compilation Unit Info + .value 0x3 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF0 # DW_AT_producer: "GNU C 4.4.4 20100726 (Red Hat 4.4.4-13)" + .byte 0x1 # DW_AT_language + .long .LASF1 # DW_AT_name: "x86-tailcall.c" + .long .LASF2 # DW_AT_comp_dir: "" + .quad .Ltext0 # DW_AT_low_pc + .quad .Letext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x2d) DW_TAG_subprogram) + .ascii "bar\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (x86-tailcall.c) + .byte 0x15 # DW_AT_decl_line + .byte 0x1 # DW_AT_prototyped + .long 0x4b # DW_AT_type + .quad .LFB0 # DW_AT_low_pc + .quad .LFE0 # DW_AT_high_pc + .byte 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + .uleb128 0x3 # (DIE (0x4b) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x2 # (DIE (0x52) DW_TAG_subprogram) + .ascii "foo\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (x86-tailcall.c) + .byte 0x1b # DW_AT_decl_line + .byte 0x1 # DW_AT_prototyped + .long 0x4b # DW_AT_type + .quad .LFB1 # DW_AT_low_pc + .quad .LFE1 # DW_AT_high_pc + .byte 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + .uleb128 0x4 # (DIE (0x70) DW_TAG_subprogram) + .byte 0x1 # DW_AT_external + .long .LASF3 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (x86-tailcall.c) + .byte 0x21 # DW_AT_decl_line + .byte 0x1 # DW_AT_prototyped + .long 0x4b # DW_AT_type + .quad .LFB2 # DW_AT_low_pc + .quad .LFE2 # DW_AT_high_pc + .byte 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + .uleb128 0x5 # (DIE (0x8f) DW_TAG_variable) + .long .LASF4 # DW_AT_name: "answer" + .byte 0x1 # DW_AT_decl_file (x86-tailcall.c) + .byte 0x23 # DW_AT_decl_line + .long 0x4b # DW_AT_type + .long .LLST0 # DW_AT_location + .byte 0x0 # end of children of DIE 0x70 + .byte 0x0 # end of children of DIE 0xb + .section .debug_abbrev + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x6 # (DW_FORM_data4) + .byte 0x0 + .byte 0x0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0xc # (DW_FORM_flag) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0xa # (DW_FORM_block1) + .byte 0x0 + .byte 0x0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0x0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0x0 + .byte 0x0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0xc # (DW_FORM_flag) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0xc # (DW_FORM_flag) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0xa # (DW_FORM_block1) + .byte 0x0 + .byte 0x0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0x0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x6 # (DW_FORM_data4) + .byte 0x0 + .byte 0x0 + .byte 0x0 + .section .debug_pubnames,"",@progbits + .long 0x17 # Length of Public Names Info + .value 0x2 # DWARF Version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .long 0xa0 # Compilation Unit Length + .long 0x70 # DIE offset + .ascii "main\0" # external name + .long 0x0 + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF Version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0x0 # Size of Segment Descriptor + .value 0x0 # Pad to 16 byte boundary + .value 0x0 + .quad .Ltext0 # Address + .quad .Letext0-.Ltext0 # Length + .quad 0x0 + .quad 0x0 + .section .debug_str,"MS",@progbits,1 +.LASF0: + .string "GNU C 4.4.4 20100726 (Red Hat 4.4.4-13)" +.LASF3: + .string "main" +.LASF4: + .string "answer" +.LASF2: + .string "" +.LASF1: + .string "x86-tailcall.c" + .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; +} |