[patch v4 17/24] record-btrace: add record goto target methods
Jan Kratochvil
jan.kratochvil@redhat.com
Sun Aug 18 19:08:00 GMT 2013
On Wed, 03 Jul 2013 11:14:27 +0200, Markus Metzger wrote:
> 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-btrace.c (record_btrace_set_replay,
> record_btrace_goto_begin, record_btrace_goto_end,
> record_btrace_goto): New.
> (init_record_btrace_ops): Initialize them.
> * NEWS: Announce it.
>
> testsuite/
> * gdb.btrace/Makefile.in (EXECUTABLES): Add record_goto.
> * gdb.btrace/record_goto.c: New.
> * gdb.btrace/record_goto.exp: New.
> * gdb.btrace/x86-record_goto.S: New.
>
>
> ---
> gdb/NEWS | 2 +
> gdb/record-btrace.c | 91 ++++++++
> gdb/testsuite/gdb.btrace/Makefile.in | 2 +-
> gdb/testsuite/gdb.btrace/record_goto.c | 51 +++++
> gdb/testsuite/gdb.btrace/record_goto.exp | 152 +++++++++++++
> gdb/testsuite/gdb.btrace/x86-record_goto.S | 332 ++++++++++++++++++++++++++++
> 6 files changed, 629 insertions(+), 1 deletions(-)
> create mode 100644 gdb/testsuite/gdb.btrace/record_goto.c
> create mode 100644 gdb/testsuite/gdb.btrace/record_goto.exp
> create mode 100644 gdb/testsuite/gdb.btrace/x86-record_goto.S
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 6ac910a..bfe4dd4 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -13,6 +13,8 @@ Nios II ELF nios2*-*-elf
> Nios II GNU/Linux nios2*-*-linux
> Texas Instruments MSP430 msp430*-*-elf
>
> +* The btrace record target supports the 'record goto' command.
> +
> * 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.
> diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
> index 2b552d5..d6508bd 100644
> --- a/gdb/record-btrace.c
> +++ b/gdb/record-btrace.c
> @@ -1023,6 +1023,94 @@ record_btrace_find_new_threads (struct target_ops *ops)
> }
> }
>
> +/* Set the replay branch trace instruction iterator. */
Describe that IT may be NULL and what that means.
(I would require IT != NULL but that does not matter much.)
> +
> +static void
> +record_btrace_set_replay (struct btrace_thread_info *btinfo,
> + const struct btrace_insn_iterator *it)
> +{
> + if (it == NULL || it->function == NULL)
> + {
> + if (btinfo->replay == NULL)
> + return;
> +
> + xfree (btinfo->replay);
> + btinfo->replay = NULL;
> + }
> + else
> + {
> + if (btinfo->replay == NULL)
> + btinfo->replay = xzalloc (sizeof (*btinfo->replay));
xmalloc, a nitpick.
> + else if (btrace_insn_cmp (btinfo->replay, it) == 0)
> + return;
> +
> + *btinfo->replay = *it;
> + }
> +
> + /* Clear the function call and instruction histories so we start anew
> + from the new replay position. */
> + xfree (btinfo->insn_history);
> + xfree (btinfo->call_history);
> +
> + btinfo->insn_history = NULL;
> + btinfo->call_history = NULL;
> +
> + registers_changed ();
> + reinit_frame_cache ();
> + print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
> +}
> +
> +/* The to_goto_record_begin method of target record-btrace. */
> +
> +static void
> +record_btrace_goto_begin (void)
> +{
> + struct btrace_thread_info *btinfo;
> + struct btrace_insn_iterator begin;
> +
> + btinfo = require_btrace ();
> +
> + btrace_insn_begin (&begin, btinfo);
> + record_btrace_set_replay (btinfo, &begin);
> +}
> +
> +/* The to_goto_record_end method of target record-btrace. */
> +
> +static void
> +record_btrace_goto_end (void)
> +{
> + struct btrace_thread_info *btinfo;
> +
> + btinfo = require_btrace ();
> +
> + record_btrace_set_replay (btinfo, NULL);
> +}
> +
> +/* The to_goto_record method of target record-btrace. */
> +
> +static void
> +record_btrace_goto (ULONGEST insn)
> +{
> + struct btrace_thread_info *btinfo;
> + struct btrace_insn_iterator it;
> + unsigned int number;
> + int found;
> +
> + number = (unsigned int) insn;
Needless cast.
> +
> + /* Check for wrap-arounds. */
> + if (number != insn)
> + error (_("Instruction number out of range."));
> +
> + btinfo = require_btrace ();
> +
> + found = btrace_find_insn_by_number (&it, btinfo, number);
> + if (found == 0)
> + error (_("No such instruction."));
> +
> + record_btrace_set_replay (btinfo, &it);
> +}
> +
> /* Initialize the record-btrace target ops. */
>
> static void
> @@ -1058,6 +1146,9 @@ init_record_btrace_ops (void)
> ops->to_resume = record_btrace_resume;
> ops->to_wait = record_btrace_wait;
> ops->to_find_new_threads = record_btrace_find_new_threads;
> + ops->to_goto_record_begin = record_btrace_goto_begin;
> + ops->to_goto_record_end = record_btrace_goto_end;
> + ops->to_goto_record = record_btrace_goto;
> ops->to_stratum = record_stratum;
> ops->to_magic = OPS_MAGIC;
> }
> diff --git a/gdb/testsuite/gdb.btrace/Makefile.in b/gdb/testsuite/gdb.btrace/Makefile.in
> index 5c70700..aa2820a 100644
> --- a/gdb/testsuite/gdb.btrace/Makefile.in
> +++ b/gdb/testsuite/gdb.btrace/Makefile.in
> @@ -2,7 +2,7 @@ VPATH = @srcdir@
> srcdir = @srcdir@
>
> EXECUTABLES = enable function_call_history instruction_history tailcall \
> - exception
> + exception record_goto
>
> MISCELLANEOUS =
>
> diff --git a/gdb/testsuite/gdb.btrace/record_goto.c b/gdb/testsuite/gdb.btrace/record_goto.c
> new file mode 100644
> index 0000000..1250708
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/record_goto.c
> @@ -0,0 +1,51 @@
> +/* 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/>. */
> +
> +void
> +fun1 (void)
> +{
> +}
> +
> +void
> +fun2 (void)
> +{
> + fun1 ();
> +}
> +
> +void
> +fun3 (void)
> +{
> + fun1 ();
> + fun2 ();
> +}
> +
> +void
> +fun4 (void)
> +{
> + fun1 ();
> + fun2 ();
> + fun3 ();
> +}
> +
> +int
> +main (void)
> +{
> + fun4 ();
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.btrace/record_goto.exp b/gdb/testsuite/gdb.btrace/record_goto.exp
> new file mode 100644
> index 0000000..a9f9a64
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/record_goto.exp
> @@ -0,0 +1,152 @@
> +# 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-record_goto.S
> +if [prepare_for_testing record_goto.exp $testfile $srcfile] {
> + return -1
> +}
Similar arch protection + COMPILE=1 option as suggested in one of the previous
mails.
> +if ![runto_main] {
> + return -1
> +}
> +
> +# we want a small context sizes to simplify the test
> +gdb_test_no_output "set record instruction-history-size 3"
> +gdb_test_no_output "set record function-call-history-size 3"
> +
> +# trace the call to the test function
> +gdb_test_no_output "record btrace"
> +gdb_test "next"
> +
> +# start by listing all functions
> +gdb_test "record function-call-history /ci 1, +20" "
> +1\t fun4\tinst 1,3\r
> +2\t fun1\tinst 4,7\r
> +3\t fun4\tinst 8,8\r
> +4\t fun2\tinst 9,11\r
> +5\t fun1\tinst 12,15\r
> +6\t fun2\tinst 16,17\r
> +7\t fun4\tinst 18,18\r
> +8\t fun3\tinst 19,21\r
> +9\t fun1\tinst 22,25\r
> +10\t fun3\tinst 26,26\r
> +11\t fun2\tinst 27,29\r
> +12\t fun1\tinst 30,33\r
> +13\t fun2\tinst 34,35\r
> +14\t fun3\tinst 36,37\r
> +15\t fun4\tinst 38,39\r" "record_goto - list all functions"
> +
> +# let's see if we can go back in history
> +gdb_test "record goto 18" "
> +.*fun4 \\(\\) at record_goto.c:43.*" "record_goto - goto 18"
> +
> +# the function call history should start at the new location
> +gdb_test "record function-call-history /ci" "
> +7\t fun4\tinst 18,18\r
> +8\t fun3\tinst 19,21\r
> +9\t fun1\tinst 22,25\r" "record_goto - function-call-history from 18 forwards"
> +
> +# the instruciton history should start at the new location
> +gdb_test "record instruction-history" "
> +18.*\r
> +19.*\r
> +20.*\r" "record_goto - instruciton-history from 18 forwards"
> +
> +# let's go to another place in the history
> +gdb_test "record goto 26" "
> +.*fun3 \\(\\) at record_goto.c:35.*" "record_goto - goto 26"
> +
> +# the function call history should start at the new location
> +gdb_test "record function-call-history /ci -" "
> +8\t fun3\tinst 19,21\r
> +9\t fun1\tinst 22,25\r
> +10\t fun3\tinst 26,26\r" "record_goto - function-call-history from 26 backwards"
> +
> +# the instruciton history should start at the new location
> +gdb_test "record instruction-history -" "
> +24.*\r
> +25.*\r
> +26.*\r" "record_goto - instruciton-history from 26 backwards"
> +
> +# test that we can go to the begin of the trace
> +gdb_test "record goto begin" "
> +.*fun4 \\(\\) at record_goto.c:40.*" "record_goto - goto begin"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record function-call-history /ci -" "
> +1\t fun4\tinst 1,3\r
> +2\t fun1\tinst 4,7\r
> +3\t fun4\tinst 8,8\r" "record_goto - function-call-history from begin backwards"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record instruction-history -" "
> +1.*\r
> +2.*\r
> +3.*\r" "record_goto - instruciton-history from begin backwards"
> +
> +# we should get the exact same history from the first instruction
> +gdb_test "record goto 2" "
> +.*fun4 \\(\\) at record_goto.c:40.*" "record_goto - goto 2"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record function-call-history /ci -" "
> +1\t fun4\tinst 1,3\r
> +2\t fun1\tinst 4,7\r
> +3\t fun4\tinst 8,8\r" "record_goto - function-call-history from 2 backwards"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record instruction-history -" "
> +1.*\r
> +2.*\r
> +3.*\r" "record_goto - instruciton-history from 2 backwards"
> +
> +# check that we can go to the end of the trace
> +gdb_test "record goto end" "
> +.*main \\(\\) at record_goto.c:50.*" "record_goto - goto end"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record function-call-history /ci" "
> +13\t fun2\tinst 34,35\r
> +14\t fun3\tinst 36,37\r
> +15\t fun4\tinst 38,39\r" "record_goto - function-call-history from end forwards"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record instruction-history" "
> +37.*\r
> +38.*\r
> +39.*\r" "record_goto - instruciton-history from end forwards"
> +
> +# we should get the exact same history from the second to last instruction
> +gdb_test "record goto 38" "
> +.*fun4 \\(\\) at record_goto.c:44.*" "record_goto - goto 38"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record function-call-history /ci" "
> +13\t fun2\tinst 34,35\r
> +14\t fun3\tinst 36,37\r
> +15\t fun4\tinst 38,39\r" "record_goto - function-call-history from 38 forwards"
> +
> +# check that we're filling up the context correctly
> +gdb_test "record instruction-history" "
> +37.*\r
> +38.*\r
> +39.*\r" "record_goto - instruciton-history from 38 forwards"
> diff --git a/gdb/testsuite/gdb.btrace/x86-record_goto.S b/gdb/testsuite/gdb.btrace/x86-record_goto.S
> new file mode 100644
> index 0000000..d2e6621
> --- /dev/null
> +++ b/gdb/testsuite/gdb.btrace/x86-record_goto.S
> @@ -0,0 +1,332 @@
> +/* 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 -g record_goto.c -o x86-record_goto.S */
Again -dA is more convenient.
> +
> + .file "record_goto.c"
> + .section .debug_abbrev,"",@progbits
> +.Ldebug_abbrev0:
> + .section .debug_info,"",@progbits
> +.Ldebug_info0:
> + .section .debug_line,"",@progbits
> +.Ldebug_line0:
> + .text
> +.Ltext0:
> +.globl fun1
> + .type fun1, @function
> +fun1:
> +.LFB0:
> + .file 1 "record_goto.c"
> + .loc 1 22 0
> + .cfi_startproc
> + pushq %rbp
> + .cfi_def_cfa_offset 16
> + movq %rsp, %rbp
> + .cfi_offset 6, -16
> + .cfi_def_cfa_register 6
> + .loc 1 23 0
> + leave
> + .cfi_def_cfa 7, 8
> + ret
> + .cfi_endproc
> +.LFE0:
> + .size fun1, .-fun1
> +.globl fun2
> + .type fun2, @function
> +fun2:
> +.LFB1:
> + .loc 1 27 0
> + .cfi_startproc
> + pushq %rbp
> + .cfi_def_cfa_offset 16
> + movq %rsp, %rbp
> + .cfi_offset 6, -16
> + .cfi_def_cfa_register 6
> + .loc 1 28 0
> + call fun1
> + .loc 1 29 0
> + leave
> + .cfi_def_cfa 7, 8
> + ret
> + .cfi_endproc
> +.LFE1:
> + .size fun2, .-fun2
> +.globl fun3
> + .type fun3, @function
> +fun3:
> +.LFB2:
> + .loc 1 33 0
> + .cfi_startproc
> + pushq %rbp
> + .cfi_def_cfa_offset 16
> + movq %rsp, %rbp
> + .cfi_offset 6, -16
> + .cfi_def_cfa_register 6
> + .loc 1 34 0
> + call fun1
> + .loc 1 35 0
> + call fun2
> + .loc 1 36 0
> + leave
> + .cfi_def_cfa 7, 8
> + ret
> + .cfi_endproc
> +.LFE2:
> + .size fun3, .-fun3
> +.globl fun4
> + .type fun4, @function
> +fun4:
> +.LFB3:
> + .loc 1 40 0
> + .cfi_startproc
> + pushq %rbp
> + .cfi_def_cfa_offset 16
> + movq %rsp, %rbp
> + .cfi_offset 6, -16
> + .cfi_def_cfa_register 6
> + .loc 1 41 0
> + call fun1
> + .loc 1 42 0
> + call fun2
> + .loc 1 43 0
> + call fun3
> + .loc 1 44 0
> + leave
> + .cfi_def_cfa 7, 8
> + ret
> + .cfi_endproc
> +.LFE3:
> + .size fun4, .-fun4
> +.globl main
> + .type main, @function
> +main:
> +.LFB4:
> + .loc 1 48 0
> + .cfi_startproc
> + pushq %rbp
> + .cfi_def_cfa_offset 16
> + movq %rsp, %rbp
> + .cfi_offset 6, -16
> + .cfi_def_cfa_register 6
> + .loc 1 49 0
> + call fun4
> + .loc 1 50 0
> + movl $0, %eax
> + .loc 1 51 0
> + leave
> + .cfi_def_cfa 7, 8
> + ret
> + .cfi_endproc
> +.LFE4:
> + .size main, .-main
> +.Letext0:
> + .section .debug_info
> + .long 0xbc
> + .value 0x3
> + .long .Ldebug_abbrev0
> + .byte 0x8
> + .uleb128 0x1
> + .long .LASF4
> + .byte 0x1
> + .long .LASF5
> + .long .LASF6
> + .quad .Ltext0
> + .quad .Letext0
> + .long .Ldebug_line0
> + .uleb128 0x2
> + .byte 0x1
> + .long .LASF0
> + .byte 0x1
> + .byte 0x15
> + .byte 0x1
> + .quad .LFB0
> + .quad .LFE0
> + .byte 0x1
> + .byte 0x9c
> + .uleb128 0x2
> + .byte 0x1
> + .long .LASF1
> + .byte 0x1
> + .byte 0x1a
> + .byte 0x1
> + .quad .LFB1
> + .quad .LFE1
> + .byte 0x1
> + .byte 0x9c
> + .uleb128 0x2
> + .byte 0x1
> + .long .LASF2
> + .byte 0x1
> + .byte 0x20
> + .byte 0x1
> + .quad .LFB2
> + .quad .LFE2
> + .byte 0x1
> + .byte 0x9c
> + .uleb128 0x2
> + .byte 0x1
> + .long .LASF3
> + .byte 0x1
> + .byte 0x27
> + .byte 0x1
> + .quad .LFB3
> + .quad .LFE3
> + .byte 0x1
> + .byte 0x9c
> + .uleb128 0x3
> + .byte 0x1
> + .long .LASF7
> + .byte 0x1
> + .byte 0x2f
> + .byte 0x1
> + .long 0xb8
> + .quad .LFB4
> + .quad .LFE4
> + .byte 0x1
> + .byte 0x9c
> + .uleb128 0x4
> + .byte 0x4
> + .byte 0x5
> + .string "int"
> + .byte 0x0
> + .section .debug_abbrev
> + .uleb128 0x1
> + .uleb128 0x11
> + .byte 0x1
> + .uleb128 0x25
> + .uleb128 0xe
> + .uleb128 0x13
> + .uleb128 0xb
> + .uleb128 0x3
> + .uleb128 0xe
> + .uleb128 0x1b
> + .uleb128 0xe
> + .uleb128 0x11
> + .uleb128 0x1
> + .uleb128 0x12
> + .uleb128 0x1
> + .uleb128 0x10
> + .uleb128 0x6
> + .byte 0x0
> + .byte 0x0
> + .uleb128 0x2
> + .uleb128 0x2e
> + .byte 0x0
> + .uleb128 0x3f
> + .uleb128 0xc
> + .uleb128 0x3
> + .uleb128 0xe
> + .uleb128 0x3a
> + .uleb128 0xb
> + .uleb128 0x3b
> + .uleb128 0xb
> + .uleb128 0x27
> + .uleb128 0xc
> + .uleb128 0x11
> + .uleb128 0x1
> + .uleb128 0x12
> + .uleb128 0x1
> + .uleb128 0x40
> + .uleb128 0xa
> + .byte 0x0
> + .byte 0x0
> + .uleb128 0x3
> + .uleb128 0x2e
> + .byte 0x0
> + .uleb128 0x3f
> + .uleb128 0xc
> + .uleb128 0x3
> + .uleb128 0xe
> + .uleb128 0x3a
> + .uleb128 0xb
> + .uleb128 0x3b
> + .uleb128 0xb
> + .uleb128 0x27
> + .uleb128 0xc
> + .uleb128 0x49
> + .uleb128 0x13
> + .uleb128 0x11
> + .uleb128 0x1
> + .uleb128 0x12
> + .uleb128 0x1
> + .uleb128 0x40
> + .uleb128 0xa
> + .byte 0x0
> + .byte 0x0
> + .uleb128 0x4
> + .uleb128 0x24
> + .byte 0x0
> + .uleb128 0xb
> + .uleb128 0xb
> + .uleb128 0x3e
> + .uleb128 0xb
> + .uleb128 0x3
> + .uleb128 0x8
> + .byte 0x0
> + .byte 0x0
> + .byte 0x0
> + .section .debug_pubnames,"",@progbits
> + .long 0x3b
> + .value 0x2
> + .long .Ldebug_info0
> + .long 0xc0
> + .long 0x2d
> + .string "fun1"
> + .long 0x48
> + .string "fun2"
> + .long 0x63
> + .string "fun3"
> + .long 0x7e
> + .string "fun4"
> + .long 0x99
> + .string "main"
> + .long 0x0
> + .section .debug_aranges,"",@progbits
> + .long 0x2c
> + .value 0x2
> + .long .Ldebug_info0
> + .byte 0x8
> + .byte 0x0
> + .value 0x0
> + .value 0x0
> + .quad .Ltext0
> + .quad .Letext0-.Ltext0
> + .quad 0x0
> + .quad 0x0
> + .section .debug_str,"MS",@progbits,1
> +.LASF3:
> + .string "fun4"
> +.LASF5:
> + .string "record_goto.c"
> +.LASF4:
> + .string "GNU C 4.4.4 20100726 (Red Hat 4.4.4-13)"
> +.LASF7:
> + .string "main"
> +.LASF1:
> + .string "fun2"
> +.LASF0:
> + .string "fun1"
> +.LASF6:
> + .string "/users/mmetzger/gdb/gerrit/git/gdb/testsuite/gdb.btrace"
Again better to just put there "".
> +.LASF2:
> + .string "fun3"
> + .ident "GCC: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)"
> + .section .note.GNU-stack,"",@progbits
> --
> 1.7.1
More information about the Gdb-patches
mailing list