gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Mon, 17 Sep 2012 07:09:35 +0000 (07:09 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Mon, 17 Sep 2012 07:09:35 +0000 (07:09 +0000)
PR 14548
* infrun.c (handle_inferior_event): Do not reverse-continue back to the
function start if we are already at function start.  Both for
reverse-next and for reverse-step into function without line number
info.

gdb/testsuite/
PR 14548
* gdb.reverse/singlejmp-reverse-nodebug.S: New file.
* gdb.reverse/singlejmp-reverse-nodebug.c: New file.
* gdb.reverse/singlejmp-reverse.S: New file.
* gdb.reverse/singlejmp-reverse.c: New file.
* gdb.reverse/singlejmp-reverse.exp: New file.

gdb/ChangeLog
gdb/infrun.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.reverse/singlejmp-reverse-nodebug.S [new file with mode: 0644]
gdb/testsuite/gdb.reverse/singlejmp-reverse-nodebug.c [new file with mode: 0644]
gdb/testsuite/gdb.reverse/singlejmp-reverse.S [new file with mode: 0644]
gdb/testsuite/gdb.reverse/singlejmp-reverse.c [new file with mode: 0644]
gdb/testsuite/gdb.reverse/singlejmp-reverse.exp [new file with mode: 0644]

index 141b98c..b504479 100644 (file)
@@ -1,4 +1,13 @@
 2012-09-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+           Pedro Alves  <palves@redhat.com>
+
+       PR 14548
+       * infrun.c (handle_inferior_event): Do not reverse-continue back to the
+       function start if we are already at function start.  Both for
+       reverse-next and for reverse-step into function without line number
+       info.
+
+2012-09-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Code cleanup - rename 'inline' depth to 'artificial' depth.
        * breakpoint.c (set_momentary_breakpoint): Rename at a caller to
index cbab993..20207ed 100644 (file)
@@ -4902,14 +4902,22 @@ process_event_stop_test:
 
          if (execution_direction == EXEC_REVERSE)
            {
-             struct symtab_and_line sr_sal;
-
-             /* Normal function call return (static or dynamic).  */
-             init_sal (&sr_sal);
-             sr_sal.pc = ecs->stop_func_start;
-             sr_sal.pspace = get_frame_program_space (frame);
-             insert_step_resume_breakpoint_at_sal (gdbarch,
-                                                   sr_sal, null_frame_id);
+             /* If we're already at the start of the function, we've either
+                just stepped backward into a single instruction function,
+                or stepped back out of a signal handler to the first instruction
+                of the function.  Just keep going, which will single-step back
+                to the caller.  */
+             if (ecs->stop_func_start != stop_pc)
+               {
+                 struct symtab_and_line sr_sal;
+
+                 /* Normal function call return (static or dynamic).  */
+                 init_sal (&sr_sal);
+                 sr_sal.pc = ecs->stop_func_start;
+                 sr_sal.pspace = get_frame_program_space (frame);
+                 insert_step_resume_breakpoint_at_sal (gdbarch,
+                                                       sr_sal, null_frame_id);
+               }
            }
          else
            insert_step_resume_breakpoint_at_caller (frame);
@@ -4979,15 +4987,23 @@ process_event_stop_test:
 
       if (execution_direction == EXEC_REVERSE)
        {
-         /* Set a breakpoint at callee's start address.
-            From there we can step once and be back in the caller.  */
-         struct symtab_and_line sr_sal;
+         /* If we're already at the start of the function, we've either just
+            stepped backward into a single instruction function without line
+            number info, or stepped back out of a signal handler to the first
+            instruction of the function without line number info.  Just keep
+            going, which will single-step back to the caller.  */
+         if (ecs->stop_func_start != stop_pc)
+           {
+             /* Set a breakpoint at callee's start address.
+                From there we can step once and be back in the caller.  */
+             struct symtab_and_line sr_sal;
 
-         init_sal (&sr_sal);
-         sr_sal.pc = ecs->stop_func_start;
-         sr_sal.pspace = get_frame_program_space (frame);
-         insert_step_resume_breakpoint_at_sal (gdbarch,
-                                               sr_sal, null_frame_id);
+             init_sal (&sr_sal);
+             sr_sal.pc = ecs->stop_func_start;
+             sr_sal.pspace = get_frame_program_space (frame);
+             insert_step_resume_breakpoint_at_sal (gdbarch,
+                                                   sr_sal, null_frame_id);
+           }
        }
       else
        /* Set a breakpoint at callee's return address (the address
index c5da0cc..be19096 100644 (file)
@@ -1,3 +1,12 @@
+2012-09-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       PR 14548
+       * gdb.reverse/singlejmp-reverse-nodebug.S: New file.
+       * gdb.reverse/singlejmp-reverse-nodebug.c: New file.
+       * gdb.reverse/singlejmp-reverse.S: New file.
+       * gdb.reverse/singlejmp-reverse.c: New file.
+       * gdb.reverse/singlejmp-reverse.exp: New file.
+
 2012-09-16  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Fix compatibility with old GCC (~4.1).
diff --git a/gdb/testsuite/gdb.reverse/singlejmp-reverse-nodebug.S b/gdb/testsuite/gdb.reverse/singlejmp-reverse-nodebug.S
new file mode 100644 (file)
index 0000000..f5f0a7c
--- /dev/null
@@ -0,0 +1,37 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   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 source file was generated by:
+   gcc -o gdb.reverse/singlejmp-reverse-nodebug.S gdb.reverse/singlejmp-reverse-nodebug.c -Wall -S -O2
+   */
+
+       .file   "singlejmp-reverse-nodebug.c"
+       .text
+       .p2align 4,,15
+       .globl  nodebug
+       .type   nodebug, @function
+nodebug:
+.LFB0:
+       .cfi_startproc
+       # basic block 2
+       rep
+       ret
+       .cfi_endproc
+.LFE0:
+       .size   nodebug, .-nodebug
+       .ident  "GCC: (GNU) 4.6.4 20120911 (prerelease)"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.reverse/singlejmp-reverse-nodebug.c b/gdb/testsuite/gdb.reverse/singlejmp-reverse-nodebug.c
new file mode 100644 (file)
index 0000000..965f803
--- /dev/null
@@ -0,0 +1,21 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   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
+nodebug (void)
+{
+}
diff --git a/gdb/testsuite/gdb.reverse/singlejmp-reverse.S b/gdb/testsuite/gdb.reverse/singlejmp-reverse.S
new file mode 100644 (file)
index 0000000..04d7b9a
--- /dev/null
@@ -0,0 +1,311 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   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 source file was generated by:
+   gcc -o gdb.reverse/singlejmp-reverse.S gdb.reverse/singlejmp-reverse.c -Wall -S -dA -O2 -g
+   */
+
+       .file   "singlejmp-reverse.c"
+       .text
+.Ltext0:
+       .p2align 4,,15
+       .type   g, @function
+g:
+.LFB0:
+       .file 1 "gdb.reverse/singlejmp-reverse.c"
+       # gdb.reverse/singlejmp-reverse.c:22
+       .loc 1 22 0
+       .cfi_startproc
+       # basic block 2
+       # gdb.reverse/singlejmp-reverse.c:23
+       .loc 1 23 0
+       movl    $2, v(%rip)
+       # gdb.reverse/singlejmp-reverse.c:24
+       .loc 1 24 0
+       ret
+       .cfi_endproc
+.LFE0:
+       .size   g, .-g
+       .p2align 4,,15
+       .type   f, @function
+f:
+.LFB1:
+       # gdb.reverse/singlejmp-reverse.c:28
+       .loc 1 28 0
+       .cfi_startproc
+       # basic block 2
+       # gdb.reverse/singlejmp-reverse.c:29
+       .loc 1 29 0
+       jmp     g
+       .cfi_endproc
+.LFE1:
+       .size   f, .-f
+       .section        .text.startup,"ax",@progbits
+       .p2align 4,,15
+       .globl  main
+       .type   main, @function
+main:
+.LFB2:
+       # gdb.reverse/singlejmp-reverse.c:36
+       .loc 1 36 0
+       .cfi_startproc
+       # basic block 2
+       subq    $8, %rsp
+.LCFI0:
+       .cfi_def_cfa_offset 16
+       # gdb.reverse/singlejmp-reverse.c:37
+       .loc 1 37 0
+       movl    $1, v(%rip)
+       # gdb.reverse/singlejmp-reverse.c:38
+       .loc 1 38 0
+       call    f
+       # gdb.reverse/singlejmp-reverse.c:39
+       .loc 1 39 0
+       call    nodebug
+       # gdb.reverse/singlejmp-reverse.c:40
+       .loc 1 40 0
+       movl    $3, v(%rip)
+       # gdb.reverse/singlejmp-reverse.c:42
+       .loc 1 42 0
+       xorl    %eax, %eax
+       addq    $8, %rsp
+.LCFI1:
+       .cfi_def_cfa_offset 8
+       ret
+       .cfi_endproc
+.LFE2:
+       .size   main, .-main
+       .comm   v,4,4
+       .text
+.Letext0:
+       .section        .debug_info,"",@progbits
+.Ldebug_info0:
+       .long   0xa1    # Length of Compilation Unit Info
+       .value  0x2     # 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.6.4 20120911 (prerelease)"
+       .byte   0x1     # DW_AT_language
+       .long   .LASF1  # DW_AT_name: "gdb.reverse/singlejmp-reverse.c"
+       .long   .LASF2  # DW_AT_comp_dir: ""
+       .quad   0       # DW_AT_low_pc
+       .quad   0       # DW_AT_entry_pc
+       .long   .Ldebug_ranges0+0       # DW_AT_ranges
+       .long   .Ldebug_line0   # DW_AT_stmt_list
+       .uleb128 0x2    # (DIE (0x31) DW_TAG_subprogram)
+       .ascii "g\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (gdb.reverse/singlejmp-reverse.c)
+       .byte   0x15    # DW_AT_decl_line
+       .byte   0x1     # DW_AT_prototyped
+       .quad   .LFB0   # DW_AT_low_pc
+       .quad   .LFE0   # DW_AT_high_pc
+       .byte   0x2     # DW_AT_frame_base
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .uleb128 0x2    # (DIE (0x4a) DW_TAG_subprogram)
+       .ascii "f\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (gdb.reverse/singlejmp-reverse.c)
+       .byte   0x1b    # DW_AT_decl_line
+       .byte   0x1     # DW_AT_prototyped
+       .quad   .LFB1   # DW_AT_low_pc
+       .quad   .LFE1   # DW_AT_high_pc
+       .byte   0x2     # DW_AT_frame_base
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .uleb128 0x3    # (DIE (0x63) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF3  # DW_AT_name: "main"
+       .byte   0x1     # DW_AT_decl_file (gdb.reverse/singlejmp-reverse.c)
+       .byte   0x23    # DW_AT_decl_line
+       .byte   0x1     # DW_AT_prototyped
+       .long   0x84    # DW_AT_type
+       .quad   .LFB2   # DW_AT_low_pc
+       .quad   .LFE2   # DW_AT_high_pc
+       .long   .LLST0  # DW_AT_frame_base
+       .uleb128 0x4    # (DIE (0x84) DW_TAG_base_type)
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0x5     # DW_AT_encoding
+       .ascii "int\0"  # DW_AT_name
+       .uleb128 0x5    # (DIE (0x8b) DW_TAG_variable)
+       .ascii "v\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (gdb.reverse/singlejmp-reverse.c)
+       .byte   0x12    # DW_AT_decl_line
+       .long   0x9f    # DW_AT_type
+       .byte   0x1     # DW_AT_external
+       .byte   0x9     # DW_AT_location
+       .byte   0x3     # DW_OP_addr
+       .quad   v
+       .uleb128 0x6    # (DIE (0x9f) DW_TAG_volatile_type)
+       .long   0x84    # DW_AT_type
+       .byte   0       # end of children of DIE 0xb
+       .section        .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+       .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 0x52   # (DW_AT_entry_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x55   # (DW_AT_ranges)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .uleb128 0x10   # (DW_AT_stmt_list)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .byte   0
+       .byte   0
+       .uleb128 0x2    # (abbrev code)
+       .uleb128 0x2e   # (TAG: DW_TAG_subprogram)
+       .byte   0       # 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 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   0
+       .byte   0
+       .uleb128 0x3    # (abbrev code)
+       .uleb128 0x2e   # (TAG: DW_TAG_subprogram)
+       .byte   0       # DW_children_no
+       .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 0x6    # (DW_FORM_data4)
+       .byte   0
+       .byte   0
+       .uleb128 0x4    # (abbrev code)
+       .uleb128 0x24   # (TAG: DW_TAG_base_type)
+       .byte   0       # 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   0
+       .byte   0
+       .uleb128 0x5    # (abbrev code)
+       .uleb128 0x34   # (TAG: DW_TAG_variable)
+       .byte   0       # 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 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x3f   # (DW_AT_external)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x2    # (DW_AT_location)
+       .uleb128 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0x6    # (abbrev code)
+       .uleb128 0x35   # (TAG: DW_TAG_volatile_type)
+       .byte   0       # DW_children_no
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .byte   0
+       .section        .debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+       .quad   .LFB2   # Location list begin address (*.LLST0)
+       .quad   .LCFI0  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI0  # Location list begin address (*.LLST0)
+       .quad   .LCFI1  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI1  # Location list begin address (*.LLST0)
+       .quad   .LFE2   # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST0)
+       .quad   0       # Location list terminator end (*.LLST0)
+       .section        .debug_aranges,"",@progbits
+       .long   0x3c    # Length of Address Ranges Info
+       .value  0x2     # DWARF Version
+       .long   .Ldebug_info0   # Offset of Compilation Unit Info
+       .byte   0x8     # Size of Address
+       .byte   0       # Size of Segment Descriptor
+       .value  0       # Pad to 16 byte boundary
+       .value  0
+       .quad   .Ltext0 # Address
+       .quad   .Letext0-.Ltext0        # Length
+       .quad   .LFB2   # Address
+       .quad   .LFE2-.LFB2     # Length
+       .quad   0
+       .quad   0
+       .section        .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+       .quad   .Ltext0 # Offset 0
+       .quad   .Letext0
+       .quad   .LFB2   # Offset 0x10
+       .quad   .LFE2
+       .quad   0
+       .quad   0
+       .section        .debug_line,"",@progbits
+.Ldebug_line0:
+       .section        .debug_str,"MS",@progbits,1
+.LASF3:
+       .string "main"
+.LASF0:
+       .string "GNU C 4.6.4 20120911 (prerelease)"
+.LASF2:
+       .string ""
+.LASF1:
+       .string "gdb.reverse/singlejmp-reverse.c"
+       .ident  "GCC: (GNU) 4.6.4 20120911 (prerelease)"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.reverse/singlejmp-reverse.c b/gdb/testsuite/gdb.reverse/singlejmp-reverse.c
new file mode 100644 (file)
index 0000000..c9ebf37
--- /dev/null
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   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/>.  */
+
+volatile int v;
+
+static __attribute__ ((noinline, noclone)) void
+g (void)
+{
+  v = 2;
+}
+
+static __attribute__ ((noinline, noclone)) void
+f (void)
+{
+  g ();
+}
+
+extern void nodebug (void);
+
+int
+main (void)
+{
+  v = 1;
+  f ();
+  nodebug ();
+  v = 3;
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp b/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp
new file mode 100644 (file)
index 0000000..830a89f
--- /dev/null
@@ -0,0 +1,62 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+#
+# 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/>.
+
+if ![supports_reverse] {
+    return
+}
+
+standard_testfile ".S" "${gdb_test_file_name}-nodebug.S"
+set executable ${testfile}
+
+if [info exists COMPILE] {
+    # make check RUNTESTFLAGS="gdb.reverse/singlejmp-reverse.exp COMPILE=1"
+    if { [build_executable_from_specs ${testfile}.exp $executable {} \
+                                     ${testfile}.c {debug optimize=-O2} \
+                                     ${testfile}-nodebug.c {optimize=-O2} \
+                                     ] == -1 } {
+       return -1
+    }
+} elseif { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
+    verbose "Skipping ${testfile}."
+    return
+} elseif { [build_executable ${testfile}.exp ${testfile} \
+           [list ${srcfile} ${srcfile2}] {}] == -1 } {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] {
+    return -1
+}
+
+if [supports_process_record] {
+    gdb_test_no_output "record"
+}
+
+gdb_test "next" {v = 1;} "next to v = 1"
+gdb_test "next" {f \(\);} "next to f"
+gdb_test "next" {nodebug \(\);} "next to nodebug"
+gdb_test "next" {v = 3;} "next to v = 3"
+
+# FAIL was:
+# No more reverse-execution history.
+# {
+gdb_test "reverse-step" {nodebug \(\);}
+
+# FAIL was:
+# No more reverse-execution history.
+# {
+gdb_test "reverse-next" {f \(\);}