Remove previous frame if an error occurs when computing frame id during unwind.
authorAndrew Burgess <aburgess@broadcom.com>
Wed, 2 Apr 2014 16:02:51 +0000 (17:02 +0100)
committerAndrew Burgess <aburgess@broadcom.com>
Fri, 30 May 2014 21:36:14 +0000 (22:36 +0100)
  https://sourceware.org/ml/gdb-patches/2014-05/msg00712.html

If an error is thrown during computing a frame id then the frame is left
in existence but without a valid frame id, this will trigger internal
errors if/when the frame is later visited (for example in a backtrace).

This patch catches errors raised while computing the frame id, and
arranges for the new frame, the one without a frame id, to be removed
from the linked list of frames.

gdb/ChangeLog:

* frame.c (remove_prev_frame): New function.
(get_prev_frame_if_no_cycle): Create / discard cleanup using
remove_prev_frame.

gdb/testsuite/ChangeLog:

* gdb.arch/amd64-invalid-stack-middle.S: New file.
* gdb.arch/amd64-invalid-stack-middle.c: New file.
* gdb.arch/amd64-invalid-stack-middle.exp: New file.
* gdb.arch/amd64-invalid-stack-top.c: New file.
* gdb.arch/amd64-invalid-stack-top.exp: New file.

gdb/ChangeLog
gdb/frame.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.S [new file with mode: 0644]
gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp [new file with mode: 0644]
gdb/testsuite/gdb.arch/amd64-invalid-stack-top.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp [new file with mode: 0644]

index b86f1c7..6986a49 100644 (file)
@@ -1,3 +1,9 @@
+2014-05-30  Andrew Burgess  <aburgess@broadcom.com>
+
+       * frame.c (remove_prev_frame): New function.
+       (get_prev_frame_if_no_cycle): Create / discard cleanup using
+       remove_prev_frame.
+
 2014-05-29  Pedro Alves  <palves@redhat.com>
 
        * infrun.c (resume): Rename local 'hw_step' to 'entry_step'
index 013d602..cbff25f 100644 (file)
@@ -1738,6 +1738,22 @@ frame_register_unwind_location (struct frame_info *this_frame, int regnum,
     }
 }
 
+/* Called during frame unwinding to remove a previous frame pointer from a
+   frame passed in ARG.  */
+
+static void
+remove_prev_frame (void *arg)
+{
+  struct frame_info *this_frame, *prev_frame;
+
+  this_frame = (struct frame_info *) arg;
+  prev_frame = this_frame->prev;
+  gdb_assert (prev_frame != NULL);
+
+  prev_frame->next = NULL;
+  this_frame->prev = NULL;
+}
+
 /* Get the previous raw frame, and check that it is not identical to
    same other frame frame already in the chain.  If it is, there is
    most likely a stack cycle, so we discard it, and mark THIS_FRAME as
@@ -1750,28 +1766,36 @@ static struct frame_info *
 get_prev_frame_if_no_cycle (struct frame_info *this_frame)
 {
   struct frame_info *prev_frame;
+  struct cleanup *prev_frame_cleanup;
 
   prev_frame = get_prev_frame_raw (this_frame);
   if (prev_frame == NULL)
     return NULL;
 
-  compute_frame_id (prev_frame);
-  if (frame_stash_add (prev_frame))
-    return prev_frame;
+  /* The cleanup will remove the previous frame that get_prev_frame_raw
+     linked onto THIS_FRAME.  */
+  prev_frame_cleanup = make_cleanup (remove_prev_frame, this_frame);
 
-  /* Another frame with the same id was already in the stash.  We just
-     detected a cycle.  */
-  if (frame_debug)
+  compute_frame_id (prev_frame);
+  if (!frame_stash_add (prev_frame))
     {
-      fprintf_unfiltered (gdb_stdlog, "-> ");
-      fprint_frame (gdb_stdlog, NULL);
-      fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
+      /* Another frame with the same id was already in the stash.  We just
+        detected a cycle.  */
+      if (frame_debug)
+       {
+         fprintf_unfiltered (gdb_stdlog, "-> ");
+         fprint_frame (gdb_stdlog, NULL);
+         fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
+       }
+      this_frame->stop_reason = UNWIND_SAME_ID;
+      /* Unlink.  */
+      prev_frame->next = NULL;
+      this_frame->prev = NULL;
+      prev_frame = NULL;
     }
-  this_frame->stop_reason = UNWIND_SAME_ID;
-  /* Unlink.  */
-  prev_frame->next = NULL;
-  this_frame->prev = NULL;
-  return NULL;
+
+  discard_cleanups (prev_frame_cleanup);
+  return prev_frame;
 }
 
 /* Return a "struct frame_info" corresponding to the frame that called
index 334fd83..a8a98f5 100644 (file)
@@ -1,3 +1,11 @@
+2014-05-30  Andrew Burgess  <aburgess@broadcom.com>
+
+       * gdb.arch/amd64-invalid-stack-middle.S: New file.
+       * gdb.arch/amd64-invalid-stack-middle.c: New file.
+       * gdb.arch/amd64-invalid-stack-middle.exp: New file.
+       * gdb.arch/amd64-invalid-stack-top.c: New file.
+       * gdb.arch/amd64-invalid-stack-top.exp: New file.
+
 2014-05-30  Pedro Alves  <palves@redhat.com>
 
        PR breakpoints/17000
diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.S b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.S
new file mode 100644 (file)
index 0000000..3b4a067
--- /dev/null
@@ -0,0 +1,1410 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 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 file is compiled from gdb.arch/amd64-invalid-stack-middle.c
+   using: 'gcc -g -O0 -S -dA' and gcc version '4.7.2'.
+   Changes were then made to the CFI entry for func2.  */
+        
+       .file   "amd64-invalid-stack-middle.c"
+       .text
+.Ltext0:
+       .globl  breakpt
+       .type   breakpt, @function
+breakpt:
+.LFB0:
+       .file 1 "amd64-invalid-stack-middle.c"
+       # amd64-invalid-stack-middle.c:25
+       .loc 1 25 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI0:
+       movq    %rsp, %rbp
+.LCFI1:
+       # amd64-invalid-stack-middle.c:27
+       .loc 1 27 0
+       popq    %rbp
+.LCFI2:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE0:
+       .size   breakpt, .-breakpt
+       .globl  func5
+       .type   func5, @function
+func5:
+.LFB1:
+       # amd64-invalid-stack-middle.c:31
+       .loc 1 31 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI3:
+       movq    %rsp, %rbp
+.LCFI4:
+       # amd64-invalid-stack-middle.c:32
+       .loc 1 32 0
+       movl    $0, %eax
+       call    breakpt
+       # amd64-invalid-stack-middle.c:33
+       .loc 1 33 0
+       popq    %rbp
+.LCFI5:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE1:
+       .size   func5, .-func5
+       .globl  func4
+       .type   func4, @function
+func4:
+.LFB2:
+       # amd64-invalid-stack-middle.c:37
+       .loc 1 37 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI6:
+       movq    %rsp, %rbp
+.LCFI7:
+       # amd64-invalid-stack-middle.c:38
+       .loc 1 38 0
+       movl    $0, %eax
+       call    func5
+       # amd64-invalid-stack-middle.c:39
+       .loc 1 39 0
+       popq    %rbp
+.LCFI8:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE2:
+       .size   func4, .-func4
+       .globl  func3
+       .type   func3, @function
+func3:
+.LFB3:
+       # amd64-invalid-stack-middle.c:43
+       .loc 1 43 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI9:
+       movq    %rsp, %rbp
+.LCFI10:
+       # amd64-invalid-stack-middle.c:44
+       .loc 1 44 0
+       movl    $0, %eax
+       call    func4
+       # amd64-invalid-stack-middle.c:45
+       .loc 1 45 0
+       popq    %rbp
+.LCFI11:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE3:
+       .size   func3, .-func3
+       .globl  func2
+       .type   func2, @function
+func2:
+.LFB4:
+       # amd64-invalid-stack-middle.c:49
+       .loc 1 49 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI12:
+       movq    %rsp, %rbp
+.LCFI13:
+       subq    $8, %rsp
+       movq    %rdi, -8(%rbp)
+       # amd64-invalid-stack-middle.c:50
+       .loc 1 50 0
+       movl    $0, %eax
+       call    func3
+       # amd64-invalid-stack-middle.c:51
+       .loc 1 51 0
+       leave
+.LCFI14:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE4:
+       .size   func2, .-func2
+       .globl  func1
+       .type   func1, @function
+func1:
+.LFB5:
+       # amd64-invalid-stack-middle.c:55
+       .loc 1 55 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI15:
+       movq    %rsp, %rbp
+.LCFI16:
+       subq    $8, %rsp
+       movq    %rdi, -8(%rbp)
+       # amd64-invalid-stack-middle.c:56
+       .loc 1 56 0
+       movq    -8(%rbp), %rax
+       movq    %rax, %rdi
+       call    func2
+       # amd64-invalid-stack-middle.c:57
+       .loc 1 57 0
+       leave
+.LCFI17:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE5:
+       .size   func1, .-func1
+       .section        .rodata
+.LC0:
+       .string "amd64-invalid-stack-middle.c"
+.LC1:
+       .string "ptr != ((void *) -1)"
+.LC2:
+       .string "ans == 0"
+       .text
+       .type   make_invalid_ptr, @function
+make_invalid_ptr:
+.LFB6:
+       # amd64-invalid-stack-middle.c:65
+       .loc 1 65 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI18:
+       movq    %rsp, %rbp
+.LCFI19:
+       subq    $32, %rsp
+       # amd64-invalid-stack-middle.c:69
+       .loc 1 69 0
+       call    getpagesize
+       movl    %eax, -4(%rbp)
+       # amd64-invalid-stack-middle.c:70
+       .loc 1 70 0
+       movl    -4(%rbp), %eax
+       cltq
+       movl    $0, %r9d
+       movl    $-1, %r8d
+       movl    $34, %ecx
+       movl    $0, %edx
+       movq    %rax, %rsi
+       movl    $0, %edi
+       call    mmap
+       movq    %rax, -16(%rbp)
+       # amd64-invalid-stack-middle.c:73
+       .loc 1 73 0
+       cmpq    $-1, -16(%rbp)
+# SUCC: 3 (fallthru) 4
+       jne     .L8
+# BLOCK 3 seq:1
+# PRED: 2 (fallthru)
+       movl    $__PRETTY_FUNCTION__.2362, %ecx
+       movl    $73, %edx
+       movl    $.LC0, %esi
+       movl    $.LC1, %edi
+# SUCC:
+       call    __assert_fail
+# BLOCK 4 seq:2
+# PRED: 2
+.L8:
+       # amd64-invalid-stack-middle.c:74
+       .loc 1 74 0
+       movl    -4(%rbp), %eax
+       movslq  %eax, %rdx
+       movq    -16(%rbp), %rax
+       movq    %rdx, %rsi
+       movq    %rax, %rdi
+       call    munmap
+       movl    %eax, -20(%rbp)
+       # amd64-invalid-stack-middle.c:75
+       .loc 1 75 0
+       cmpl    $0, -20(%rbp)
+# SUCC: 5 (fallthru) 6
+       je      .L9
+# BLOCK 5 seq:3
+# PRED: 4 (fallthru)
+       movl    $__PRETTY_FUNCTION__.2362, %ecx
+       movl    $75, %edx
+       movl    $.LC0, %esi
+       movl    $.LC2, %edi
+# SUCC:
+       call    __assert_fail
+# BLOCK 6 seq:4
+# PRED: 4
+.L9:
+       # amd64-invalid-stack-middle.c:77
+       .loc 1 77 0
+       movq    -16(%rbp), %rax
+       # amd64-invalid-stack-middle.c:78
+       .loc 1 78 0
+       leave
+.LCFI20:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE6:
+       .size   make_invalid_ptr, .-make_invalid_ptr
+       .globl  main
+       .type   main, @function
+main:
+.LFB7:
+       # amd64-invalid-stack-middle.c:82
+       .loc 1 82 0
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+       pushq   %rbp
+.LCFI21:
+       movq    %rsp, %rbp
+.LCFI22:
+       subq    $16, %rsp
+       # amd64-invalid-stack-middle.c:85
+       .loc 1 85 0
+       call    make_invalid_ptr
+       movq    %rax, -8(%rbp)
+       # amd64-invalid-stack-middle.c:86
+       .loc 1 86 0
+       movq    -8(%rbp), %rax
+       movq    %rax, %rdi
+       call    func1
+       # amd64-invalid-stack-middle.c:88
+       .loc 1 88 0
+       movl    $0, %eax
+       # amd64-invalid-stack-middle.c:89
+       .loc 1 89 0
+       leave
+.LCFI23:
+# SUCC: EXIT [100.0%] 
+       ret
+.LFE7:
+       .size   main, .-main
+       .section        .rodata
+       .align 16
+       .type   __PRETTY_FUNCTION__.2362, @object
+       .size   __PRETTY_FUNCTION__.2362, 17
+__PRETTY_FUNCTION__.2362:
+       .string "make_invalid_ptr"
+#APP
+       .section        .debug_frame,"",@progbits
+.Lframe0:
+       .long   .LECIE0-.LSCIE0 # Length of Common Information Entry
+.LSCIE0:
+       .long   0xffffffff      # CIE Identifier Tag
+       .byte   0x1     # CIE Version
+       .ascii "\0"     # CIE Augmentation
+       .uleb128 0x1    # CIE Code Alignment Factor
+       .sleb128 -8     # CIE Data Alignment Factor
+       .byte   0x10    # CIE RA Column
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .byte   0x90    # DW_CFA_offset, column 0x10
+       .uleb128 0x1
+       .align 8
+.LECIE0:
+.LSFDE0:
+       .long   .LEFDE0-.LASFDE0        # FDE Length
+.LASFDE0:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB0   # FDE initial location
+       .quad   .LFE0-.LFB0     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI0-.LFB0
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI1-.LCFI0
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI2-.LCFI1
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE0:
+.LSFDE2:
+       .long   .LEFDE2-.LASFDE2        # FDE Length
+.LASFDE2:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB1   # FDE initial location
+       .quad   .LFE1-.LFB1     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI3-.LFB1
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI4-.LCFI3
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI5-.LCFI4
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE2:
+.LSFDE4:
+       .long   .LEFDE4-.LASFDE4        # FDE Length
+.LASFDE4:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB2   # FDE initial location
+       .quad   .LFE2-.LFB2     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI6-.LFB2
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI7-.LCFI6
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI8-.LCFI7
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE4:
+.LSFDE6:
+       .long   .LEFDE6-.LASFDE6        # FDE Length
+.LASFDE6:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB3   # FDE initial location
+       .quad   .LFE3-.LFB3     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI9-.LFB3
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI10-.LCFI9
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI11-.LCFI10
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE6:
+.LSFDE8:
+       .long   .LEFDE8-.LASFDE8        # FDE Length
+.LASFDE8:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB4           # FDE initial location
+       .quad   .LFE4-.LFB4     # FDE address range
+        .byte 0xf              # DW_CFA_def_cfa_expression
+        .uleb128 .LEDWBLK1 - .LSDWBLK1
+.LSDWBLK1:
+        .byte 0x75              # DW_OP_breg5
+        .sleb128 0x0            #        offset
+        .byte 0x94              # DW_OP_dref_size
+        .byte 0x8              #        size
+.LEDWBLK1:
+       .align 8                # Padding.
+.LEFDE8:
+.LSFDE10:
+       .long   .LEFDE10-.LASFDE10      # FDE Length
+.LASFDE10:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB5   # FDE initial location
+       .quad   .LFE5-.LFB5     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI15-.LFB5
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI16-.LCFI15
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI17-.LCFI16
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE10:
+.LSFDE12:
+       .long   .LEFDE12-.LASFDE12      # FDE Length
+.LASFDE12:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB6   # FDE initial location
+       .quad   .LFE6-.LFB6     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI18-.LFB6
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI19-.LCFI18
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI20-.LCFI19
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE12:
+.LSFDE14:
+       .long   .LEFDE14-.LASFDE14      # FDE Length
+.LASFDE14:
+       .long   .Lframe0        # FDE CIE offset
+       .quad   .LFB7   # FDE initial location
+       .quad   .LFE7-.LFB7     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI21-.LFB7
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI22-.LCFI21
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI23-.LCFI22
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE14:
+#NO_APP
+#APP
+       .section        .eh_frame,"a",@progbits
+.Lframe1:
+       .long   .LECIE1-.LSCIE1 # Length of Common Information Entry
+.LSCIE1:
+       .long   0       # CIE Identifier Tag
+       .byte   0x1     # CIE Version
+       .ascii "zR\0"   # CIE Augmentation
+       .uleb128 0x1    # CIE Code Alignment Factor
+       .sleb128 -8     # CIE Data Alignment Factor
+       .byte   0x10    # CIE RA Column
+       .uleb128 0x1    # Augmentation size
+       .byte   0x3     # FDE Encoding (udata4)
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .byte   0x90    # DW_CFA_offset, column 0x10
+       .uleb128 0x1
+       .align 8
+.LECIE1:
+.LSFDE17:
+       .long   .LEFDE17-.LASFDE17      # FDE Length
+.LASFDE17:
+       .long   .LASFDE17-.Lframe1      # FDE CIE offset
+       .long   .LFB0   # FDE initial location
+       .long   .LFE0-.LFB0     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI0-.LFB0
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI1-.LCFI0
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI2-.LCFI1
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE17:
+.LSFDE19:
+       .long   .LEFDE19-.LASFDE19      # FDE Length
+.LASFDE19:
+       .long   .LASFDE19-.Lframe1      # FDE CIE offset
+       .long   .LFB1   # FDE initial location
+       .long   .LFE1-.LFB1     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI3-.LFB1
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI4-.LCFI3
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI5-.LCFI4
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE19:
+.LSFDE21:
+       .long   .LEFDE21-.LASFDE21      # FDE Length
+.LASFDE21:
+       .long   .LASFDE21-.Lframe1      # FDE CIE offset
+       .long   .LFB2   # FDE initial location
+       .long   .LFE2-.LFB2     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI6-.LFB2
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI7-.LCFI6
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI8-.LCFI7
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE21:
+.LSFDE23:
+       .long   .LEFDE23-.LASFDE23      # FDE Length
+.LASFDE23:
+       .long   .LASFDE23-.Lframe1      # FDE CIE offset
+       .long   .LFB3   # FDE initial location
+       .long   .LFE3-.LFB3     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI9-.LFB3
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI10-.LCFI9
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI11-.LCFI10
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE23:
+.LSFDE25:
+       .long   .LEFDE25-.LASFDE25      # FDE Length
+.LASFDE25:
+       .long   .LASFDE25-.Lframe1      # FDE CIE offset
+       .long   .LFB4   # FDE initial location
+       .long   .LFE4-.LFB4     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI12-.LFB4
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI13-.LCFI12
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI14-.LCFI13
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE25:
+.LSFDE27:
+       .long   .LEFDE27-.LASFDE27      # FDE Length
+.LASFDE27:
+       .long   .LASFDE27-.Lframe1      # FDE CIE offset
+       .long   .LFB5   # FDE initial location
+       .long   .LFE5-.LFB5     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI15-.LFB5
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI16-.LCFI15
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI17-.LCFI16
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE27:
+.LSFDE29:
+       .long   .LEFDE29-.LASFDE29      # FDE Length
+.LASFDE29:
+       .long   .LASFDE29-.Lframe1      # FDE CIE offset
+       .long   .LFB6   # FDE initial location
+       .long   .LFE6-.LFB6     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI18-.LFB6
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI19-.LCFI18
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI20-.LCFI19
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE29:
+.LSFDE31:
+       .long   .LEFDE31-.LASFDE31      # FDE Length
+.LASFDE31:
+       .long   .LASFDE31-.Lframe1      # FDE CIE offset
+       .long   .LFB7   # FDE initial location
+       .long   .LFE7-.LFB7     # FDE address range
+       .uleb128 0      # Augmentation size
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI21-.LFB7
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x10
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x2
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI22-.LCFI21
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x6
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI23-.LCFI22
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x7
+       .uleb128 0x8
+       .align 8
+.LEFDE31:
+#NO_APP
+       .text
+.Letext0:
+       .section        .debug_info,"",@progbits
+.Ldebug_info0:
+       .long   0x1f1   # 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   .LASF17 # DW_AT_producer: "GNU C 4.7.2"
+       .byte   0x1     # DW_AT_language
+       .long   .LASF18 # DW_AT_name: "amd64-invalid-stack-middle.c"
+       .long   .LASF19 # DW_AT_comp_dir: "/home/gdb/binutils-gdb/gdb/testsuite/gdb.arch"
+       .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_base_type)
+       .byte   0x8     # DW_AT_byte_size
+       .byte   0x7     # DW_AT_encoding
+       .long   .LASF0  # DW_AT_name: "long unsigned int"
+       .uleb128 0x2    # (DIE (0x34) DW_TAG_base_type)
+       .byte   0x1     # DW_AT_byte_size
+       .byte   0x8     # DW_AT_encoding
+       .long   .LASF1  # DW_AT_name: "unsigned char"
+       .uleb128 0x2    # (DIE (0x3b) DW_TAG_base_type)
+       .byte   0x2     # DW_AT_byte_size
+       .byte   0x7     # DW_AT_encoding
+       .long   .LASF2  # DW_AT_name: "short unsigned int"
+       .uleb128 0x2    # (DIE (0x42) DW_TAG_base_type)
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0x7     # DW_AT_encoding
+       .long   .LASF3  # DW_AT_name: "unsigned int"
+       .uleb128 0x2    # (DIE (0x49) DW_TAG_base_type)
+       .byte   0x1     # DW_AT_byte_size
+       .byte   0x6     # DW_AT_encoding
+       .long   .LASF4  # DW_AT_name: "signed char"
+       .uleb128 0x2    # (DIE (0x50) DW_TAG_base_type)
+       .byte   0x2     # DW_AT_byte_size
+       .byte   0x5     # DW_AT_encoding
+       .long   .LASF5  # DW_AT_name: "short int"
+       .uleb128 0x3    # (DIE (0x57) DW_TAG_base_type)
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0x5     # DW_AT_encoding
+       .ascii "int\0"  # DW_AT_name
+       .uleb128 0x2    # (DIE (0x5e) DW_TAG_base_type)
+       .byte   0x8     # DW_AT_byte_size
+       .byte   0x5     # DW_AT_encoding
+       .long   .LASF6  # DW_AT_name: "long int"
+       .uleb128 0x2    # (DIE (0x65) DW_TAG_base_type)
+       .byte   0x8     # DW_AT_byte_size
+       .byte   0x7     # DW_AT_encoding
+       .long   .LASF7  # DW_AT_name: "sizetype"
+       .uleb128 0x4    # (DIE (0x6c) DW_TAG_pointer_type)
+       .byte   0x8     # DW_AT_byte_size
+       .uleb128 0x2    # (DIE (0x6e) DW_TAG_base_type)
+       .byte   0x1     # DW_AT_byte_size
+       .byte   0x6     # DW_AT_encoding
+       .long   .LASF8  # DW_AT_name: "char"
+       .uleb128 0x5    # (DIE (0x75) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF9  # DW_AT_name: "breakpt"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x18    # DW_AT_decl_line
+       .quad   .LFB0   # DW_AT_low_pc
+       .quad   .LFE0   # DW_AT_high_pc
+       .long   .LLST0  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_call_sites
+       .uleb128 0x6    # (DIE (0x92) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF10 # DW_AT_name: "func5"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x1e    # DW_AT_decl_line
+       .quad   .LFB1   # DW_AT_low_pc
+       .quad   .LFE1   # DW_AT_high_pc
+       .long   .LLST1  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_tail_call_sites
+       .uleb128 0x6    # (DIE (0xaf) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF11 # DW_AT_name: "func4"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x24    # DW_AT_decl_line
+       .quad   .LFB2   # DW_AT_low_pc
+       .quad   .LFE2   # DW_AT_high_pc
+       .long   .LLST2  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_tail_call_sites
+       .uleb128 0x6    # (DIE (0xcc) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF12 # DW_AT_name: "func3"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x2a    # DW_AT_decl_line
+       .quad   .LFB3   # DW_AT_low_pc
+       .quad   .LFE3   # DW_AT_high_pc
+       .long   .LLST3  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_tail_call_sites
+       .uleb128 0x7    # (DIE (0xe9) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF13 # DW_AT_name: "func2"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x30    # DW_AT_decl_line
+       .byte   0x1     # DW_AT_prototyped
+       .quad   .LFB4   # DW_AT_low_pc
+       .quad   .LFE4   # DW_AT_high_pc
+       .long   .LLST4  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_tail_call_sites
+       .long   0x11a   # DW_AT_sibling
+       .uleb128 0x8    # (DIE (0x10b) DW_TAG_formal_parameter)
+       .ascii "ptr\0"  # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x30    # DW_AT_decl_line
+       .long   0x6c    # DW_AT_type
+       .byte   0x2     # DW_AT_location
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 -24
+       .byte   0       # end of children of DIE 0xe9
+       .uleb128 0x7    # (DIE (0x11a) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF14 # DW_AT_name: "func1"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x36    # DW_AT_decl_line
+       .byte   0x1     # DW_AT_prototyped
+       .quad   .LFB5   # DW_AT_low_pc
+       .quad   .LFE5   # DW_AT_high_pc
+       .long   .LLST5  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_tail_call_sites
+       .long   0x14b   # DW_AT_sibling
+       .uleb128 0x8    # (DIE (0x13c) DW_TAG_formal_parameter)
+       .ascii "ptr\0"  # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x36    # DW_AT_decl_line
+       .long   0x6c    # DW_AT_type
+       .byte   0x2     # DW_AT_location
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 -24
+       .byte   0       # end of children of DIE 0x11a
+       .uleb128 0x9    # (DIE (0x14b) DW_TAG_subprogram)
+       .long   .LASF20 # DW_AT_name: "make_invalid_ptr"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x40    # DW_AT_decl_line
+       .byte   0x1     # DW_AT_prototyped
+       .long   0x6c    # DW_AT_type
+       .quad   .LFB6   # DW_AT_low_pc
+       .quad   .LFE6   # DW_AT_high_pc
+       .long   .LLST6  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_tail_call_sites
+       .long   0x1af   # DW_AT_sibling
+       .uleb128 0xa    # (DIE (0x170) DW_TAG_variable)
+       .long   .LASF15 # DW_AT_name: "page_size"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x42    # DW_AT_decl_line
+       .long   0x57    # DW_AT_type
+       .byte   0x2     # DW_AT_location
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 -20
+       .uleb128 0xb    # (DIE (0x17e) DW_TAG_variable)
+       .ascii "ans\0"  # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x42    # DW_AT_decl_line
+       .long   0x57    # DW_AT_type
+       .byte   0x2     # DW_AT_location
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 -36
+       .uleb128 0xb    # (DIE (0x18c) DW_TAG_variable)
+       .ascii "ptr\0"  # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x43    # DW_AT_decl_line
+       .long   0x6c    # DW_AT_type
+       .byte   0x2     # DW_AT_location
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 -32
+       .uleb128 0xc    # (DIE (0x19a) DW_TAG_variable)
+       .long   .LASF21 # DW_AT_name: "__PRETTY_FUNCTION__"
+       .long   0x1bf   # DW_AT_type
+       .byte   0x1     # DW_AT_artificial
+       .byte   0x9     # DW_AT_location
+       .byte   0x3     # DW_OP_addr
+       .quad   __PRETTY_FUNCTION__.2362
+       .byte   0       # end of children of DIE 0x14b
+       .uleb128 0xd    # (DIE (0x1af) DW_TAG_array_type)
+       .long   0x6e    # DW_AT_type
+       .long   0x1bf   # DW_AT_sibling
+       .uleb128 0xe    # (DIE (0x1b8) DW_TAG_subrange_type)
+       .long   0x65    # DW_AT_type
+       .byte   0x10    # DW_AT_upper_bound
+       .byte   0       # end of children of DIE 0x1af
+       .uleb128 0xf    # (DIE (0x1bf) DW_TAG_const_type)
+       .long   0x1af   # DW_AT_type
+       .uleb128 0x10   # (DIE (0x1c4) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .long   .LASF22 # DW_AT_name: "main"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x51    # DW_AT_decl_line
+       .long   0x57    # DW_AT_type
+       .quad   .LFB7   # DW_AT_low_pc
+       .quad   .LFE7   # DW_AT_high_pc
+       .long   .LLST7  # DW_AT_frame_base
+       .byte   0x1     # DW_AT_GNU_all_tail_call_sites
+       .uleb128 0xa    # (DIE (0x1e5) DW_TAG_variable)
+       .long   .LASF16 # DW_AT_name: "invalid_ptr"
+       .byte   0x1     # DW_AT_decl_file (amd64-invalid-stack-middle.c)
+       .byte   0x53    # DW_AT_decl_line
+       .long   0x6c    # DW_AT_type
+       .byte   0x2     # DW_AT_location
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 -24
+       .byte   0       # end of children of DIE 0x1c4
+       .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 0x12   # (DW_AT_high_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x10   # (DW_AT_stmt_list)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .byte   0
+       .byte   0
+       .uleb128 0x2    # (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 0xe    # (DW_FORM_strp)
+       .byte   0
+       .byte   0
+       .uleb128 0x3    # (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 0x4    # (abbrev code)
+       .uleb128 0xf    # (TAG: DW_TAG_pointer_type)
+       .byte   0       # DW_children_no
+       .uleb128 0xb    # (DW_AT_byte_size)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .byte   0
+       .byte   0
+       .uleb128 0x5    # (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 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)
+       .uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .byte   0
+       .byte   0
+       .uleb128 0x6    # (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 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)
+       .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .byte   0
+       .byte   0
+       .uleb128 0x7    # (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 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)
+       .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x1    # (DW_AT_sibling)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0x8    # (abbrev code)
+       .uleb128 0x5    # (TAG: DW_TAG_formal_parameter)
+       .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 0x2    # (DW_AT_location)
+       .uleb128 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0x9    # (abbrev code)
+       .uleb128 0x2e   # (TAG: DW_TAG_subprogram)
+       .byte   0x1     # DW_children_yes
+       .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)
+       .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x1    # (DW_AT_sibling)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0xa    # (abbrev code)
+       .uleb128 0x34   # (TAG: DW_TAG_variable)
+       .byte   0       # 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 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0xb    # (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 0x2    # (DW_AT_location)
+       .uleb128 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0xc    # (abbrev code)
+       .uleb128 0x34   # (TAG: DW_TAG_variable)
+       .byte   0       # DW_children_no
+       .uleb128 0x3    # (DW_AT_name)
+       .uleb128 0xe    # (DW_FORM_strp)
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x34   # (DW_AT_artificial)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x2    # (DW_AT_location)
+       .uleb128 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0xd    # (abbrev code)
+       .uleb128 0x1    # (TAG: DW_TAG_array_type)
+       .byte   0x1     # DW_children_yes
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x1    # (DW_AT_sibling)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0xe    # (abbrev code)
+       .uleb128 0x21   # (TAG: DW_TAG_subrange_type)
+       .byte   0       # DW_children_no
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x2f   # (DW_AT_upper_bound)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .byte   0
+       .byte   0
+       .uleb128 0xf    # (abbrev code)
+       .uleb128 0x26   # (TAG: DW_TAG_const_type)
+       .byte   0       # DW_children_no
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0x10   # (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 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)
+       .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .byte   0
+       .byte   0
+       .byte   0
+       .section        .debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+       .quad   .LFB0-.Ltext0   # Location list begin address (*.LLST0)
+       .quad   .LCFI0-.Ltext0  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI0-.Ltext0  # Location list begin address (*.LLST0)
+       .quad   .LCFI1-.Ltext0  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI1-.Ltext0  # Location list begin address (*.LLST0)
+       .quad   .LCFI2-.Ltext0  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI2-.Ltext0  # Location list begin address (*.LLST0)
+       .quad   .LFE0-.Ltext0   # 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)
+.LLST1:
+       .quad   .LFB1-.Ltext0   # Location list begin address (*.LLST1)
+       .quad   .LCFI3-.Ltext0  # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI3-.Ltext0  # Location list begin address (*.LLST1)
+       .quad   .LCFI4-.Ltext0  # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI4-.Ltext0  # Location list begin address (*.LLST1)
+       .quad   .LCFI5-.Ltext0  # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI5-.Ltext0  # Location list begin address (*.LLST1)
+       .quad   .LFE1-.Ltext0   # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST1)
+       .quad   0       # Location list terminator end (*.LLST1)
+.LLST2:
+       .quad   .LFB2-.Ltext0   # Location list begin address (*.LLST2)
+       .quad   .LCFI6-.Ltext0  # Location list end address (*.LLST2)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI6-.Ltext0  # Location list begin address (*.LLST2)
+       .quad   .LCFI7-.Ltext0  # Location list end address (*.LLST2)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI7-.Ltext0  # Location list begin address (*.LLST2)
+       .quad   .LCFI8-.Ltext0  # Location list end address (*.LLST2)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI8-.Ltext0  # Location list begin address (*.LLST2)
+       .quad   .LFE2-.Ltext0   # Location list end address (*.LLST2)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST2)
+       .quad   0       # Location list terminator end (*.LLST2)
+.LLST3:
+       .quad   .LFB3-.Ltext0   # Location list begin address (*.LLST3)
+       .quad   .LCFI9-.Ltext0  # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI9-.Ltext0  # Location list begin address (*.LLST3)
+       .quad   .LCFI10-.Ltext0 # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI10-.Ltext0 # Location list begin address (*.LLST3)
+       .quad   .LCFI11-.Ltext0 # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI11-.Ltext0 # Location list begin address (*.LLST3)
+       .quad   .LFE3-.Ltext0   # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST3)
+       .quad   0       # Location list terminator end (*.LLST3)
+.LLST4:
+       .quad   .LFB4-.Ltext0   # Location list begin address (*.LLST4)
+       .quad   .LCFI12-.Ltext0 # Location list end address (*.LLST4)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI12-.Ltext0 # Location list begin address (*.LLST4)
+       .quad   .LCFI13-.Ltext0 # Location list end address (*.LLST4)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI13-.Ltext0 # Location list begin address (*.LLST4)
+       .quad   .LCFI14-.Ltext0 # Location list end address (*.LLST4)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI14-.Ltext0 # Location list begin address (*.LLST4)
+       .quad   .LFE4-.Ltext0   # Location list end address (*.LLST4)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST4)
+       .quad   0       # Location list terminator end (*.LLST4)
+.LLST5:
+       .quad   .LFB5-.Ltext0   # Location list begin address (*.LLST5)
+       .quad   .LCFI15-.Ltext0 # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI15-.Ltext0 # Location list begin address (*.LLST5)
+       .quad   .LCFI16-.Ltext0 # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI16-.Ltext0 # Location list begin address (*.LLST5)
+       .quad   .LCFI17-.Ltext0 # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI17-.Ltext0 # Location list begin address (*.LLST5)
+       .quad   .LFE5-.Ltext0   # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST5)
+       .quad   0       # Location list terminator end (*.LLST5)
+.LLST6:
+       .quad   .LFB6-.Ltext0   # Location list begin address (*.LLST6)
+       .quad   .LCFI18-.Ltext0 # Location list end address (*.LLST6)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI18-.Ltext0 # Location list begin address (*.LLST6)
+       .quad   .LCFI19-.Ltext0 # Location list end address (*.LLST6)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI19-.Ltext0 # Location list begin address (*.LLST6)
+       .quad   .LCFI20-.Ltext0 # Location list end address (*.LLST6)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI20-.Ltext0 # Location list begin address (*.LLST6)
+       .quad   .LFE6-.Ltext0   # Location list end address (*.LLST6)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST6)
+       .quad   0       # Location list terminator end (*.LLST6)
+.LLST7:
+       .quad   .LFB7-.Ltext0   # Location list begin address (*.LLST7)
+       .quad   .LCFI21-.Ltext0 # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   .LCFI21-.Ltext0 # Location list begin address (*.LLST7)
+       .quad   .LCFI22-.Ltext0 # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 16
+       .quad   .LCFI22-.Ltext0 # Location list begin address (*.LLST7)
+       .quad   .LCFI23-.Ltext0 # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x76    # DW_OP_breg6
+       .sleb128 16
+       .quad   .LCFI23-.Ltext0 # Location list begin address (*.LLST7)
+       .quad   .LFE7-.Ltext0   # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x77    # DW_OP_breg7
+       .sleb128 8
+       .quad   0       # Location list terminator begin (*.LLST7)
+       .quad   0       # Location list terminator end (*.LLST7)
+       .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   0       # Size of Segment Descriptor
+       .value  0       # Pad to 16 byte boundary
+       .value  0
+       .quad   .Ltext0 # Address
+       .quad   .Letext0-.Ltext0        # Length
+       .quad   0
+       .quad   0
+       .section        .debug_line,"",@progbits
+.Ldebug_line0:
+       .section        .debug_str,"MS",@progbits,1
+.LASF10:
+       .string "func5"
+.LASF20:
+       .string "make_invalid_ptr"
+.LASF21:
+       .string "__PRETTY_FUNCTION__"
+.LASF18:
+       .string "amd64-invalid-stack-middle.c"
+.LASF22:
+       .string "main"
+.LASF14:
+       .string "func1"
+.LASF17:
+       .string "GNU C 4.7.2"
+.LASF11:
+       .string "func4"
+.LASF0:
+       .string "long unsigned int"
+.LASF1:
+       .string "unsigned char"
+.LASF8:
+       .string "char"
+.LASF6:
+       .string "long int"
+.LASF15:
+       .string "page_size"
+.LASF13:
+       .string "func2"
+.LASF16:
+       .string "invalid_ptr"
+.LASF2:
+       .string "short unsigned int"
+.LASF4:
+       .string "signed char"
+.LASF9:
+       .string "breakpt"
+.LASF19:
+       .string "/home/gdb/binutils-gdb/gdb/testsuite/gdb.arch"
+.LASF5:
+       .string "short int"
+.LASF3:
+       .string "unsigned int"
+.LASF12:
+       .string "func3"
+.LASF7:
+       .string "sizetype"
+       .ident  "GCC: (GNU) 4.7.2"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c
new file mode 100644 (file)
index 0000000..05bbd1d
--- /dev/null
@@ -0,0 +1,89 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 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/>.
+*/
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <assert.h>
+
+void
+breakpt (void)
+{
+  /* Nothing.  */
+}
+
+void
+func5 (void)
+{
+  breakpt ();
+}
+
+void
+func4 (void)
+{
+  func5 ();
+}
+
+void
+func3 (void)
+{
+  func4 ();
+}
+
+void
+func2 (void *ptr)
+{
+  func3 ();
+}
+
+void
+func1 (void *ptr)
+{
+  func2 (ptr);
+}
+
+/* Finds and returns an invalid pointer, mmaps in a page, grabs a pointer
+   to it then unmaps the page again.  This is almost certainly "undefined"
+   behaviour, but should be good enough for this small test program.  */
+
+static void *
+make_invalid_ptr (void)
+{
+  int page_size, ans;
+  void *ptr;
+  
+  page_size = getpagesize ();
+  ptr =  mmap (0, page_size, PROT_NONE,
+              MAP_PRIVATE | MAP_ANONYMOUS,
+              -1, 0);
+  assert (ptr != MAP_FAILED);
+  ans = munmap (ptr, page_size);
+  assert (ans == 0);
+
+  return ptr;
+}
+
+int 
+main (void)
+{
+  void *invalid_ptr;
+
+  invalid_ptr = make_invalid_ptr ();
+  func1 (invalid_ptr);
+  
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp
new file mode 100644 (file)
index 0000000..8ad5b18
--- /dev/null
@@ -0,0 +1,108 @@
+# Copyright (C) 2014 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/>.
+
+# In this test we're looking at how gdb handles backtraces and
+# investigating the stack depth when confronted with an "invalid" stack,
+# that is a stack where the first few frames are normal, and then there's a
+# frame where the stack in unreadable.
+#
+# One interesting bug that has been observed is that gdb will sometime
+# exhibit different behaviour the first time a stack command is run
+# compared to the second (and later) times a command is run.  This is
+# because the first time a command is run gdb actually tries to figure out
+# the answer, while the second (and later) times gdb relies on the answer
+# cached from the first time.  As a result in this test each command is
+# run twice, and we restart gdb before testing each different command to
+# ensure that nothing is being cached.
+
+set opts {}
+standard_testfile .S
+
+if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
+    verbose "Skipping ${testfile}."
+    return
+}
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} $opts] } {
+    return -1
+}
+
+if ![runto breakpt] {
+    return -1
+}
+
+gdb_test "bt" "^bt\r\n#0 +breakpt *\\(\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in func5\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in func4\[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in func3\[^\r\n\]*\r\nCannot access memory at address 0x\[0-9a-f\]+" \
+        "first backtrace, with error message"
+
+send_gdb "bt\n"
+gdb_expect {
+    -re "^bt\r\n#0 +breakpt *\\(\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in func5\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in func4\[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in func3\[^\r\n\]*\r\nCannot access memory at address 0x\[0-9a-f\]+\r\n$gdb_prompt $" {
+       # Currently gdb will not display the error message associated with
+       # the truncated backtrace after the first backtrace has been
+       # completed.  Ideally, we would do this.  If this case is ever hit
+       # then we have started to display the backtrace in all cases and
+       # the xpass should becomd a pass, and the previous pass case below
+       # should be removed, or changed to a fail.
+       xpass "second backtrace, with error message"
+    }
+    -re "^bt\r\n#0 +breakpt *\\(\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in func5\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in func4\[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in func3\[^\r\n\]*\r\n$gdb_prompt $" {
+       pass "second backtrace, without error message"
+    }
+    timeout {
+       fail "second backtrace (timeout)"
+    }
+}
+
+clean_restart ${binfile}
+
+if ![runto breakpt] {
+    return -1
+}
+
+set test_name "check mi -stack-info-depth command, first time"
+send_gdb "interpreter-exec mi \"-stack-info-depth\"\n"
+gdb_expect {
+    -re "\\^done,depth=\"4\"\r\n$gdb_prompt $" {
+       pass $test_name
+    }
+    -re "\\^error,msg=\"Cannot access memory at address $hex\"\r\n$gdb_prompt $" {
+       xfail $test_name
+    }
+}
+
+gdb_test "interpreter-exec mi \"-stack-info-depth\"" \
+    "\\^done,depth=\"4\"" \
+    "check mi -stack-info-depth command, second time"
+
+clean_restart ${binfile}
+
+if ![runto breakpt] {
+    return -1
+}
+
+set test_name "check mi -stack-list-frames command, first time"
+send_gdb "interpreter-exec mi \"-stack-list-frames\"\n"
+gdb_expect {
+    -re "\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"breakpt\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"func5\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"func4\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\},frame=\{level=\"3\",addr=\"$hex\",func=\"func3\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\}\\\]\r\n$gdb_prompt $" {
+       pass $test_name
+    }
+    -re "\\^error,msg=\"Cannot access memory at address $hex\"\r\n$gdb_prompt $" {
+       xfail $test_name
+    }
+}
+
+gdb_test "interpreter-exec mi \"-stack-list-frames\"" \
+    "\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"breakpt\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"func5\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"func4\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\},frame=\{level=\"3\",addr=\"$hex\",func=\"func3\",file=\"\[^\"\]+\",fullname=\"\[^\"\]+\",line=\"${decimal}\"\}\\\]" \
+    "check mi -stack-list-frames command, second time"
diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.c b/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.c
new file mode 100644 (file)
index 0000000..168dc55
--- /dev/null
@@ -0,0 +1,73 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 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/>.
+*/
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <assert.h>
+
+void *global_invalid_ptr = NULL;
+
+void
+func2 (void)
+{
+  /* Replace the current stack pointer and frame pointer with the invalid
+     pointer.  */
+  asm ("mov %0, %%rsp\n\tmov %0, %%rbp" : : "r" (global_invalid_ptr));
+
+  /* Create a label for a breakpoint.  */
+  asm (".global breakpt\nbreakpt:");
+}
+
+void
+func1 (void *ptr)
+{
+  global_invalid_ptr = ptr;
+  func2 ();
+}
+
+/* Finds and returns an invalid pointer, mmaps in a page, grabs a pointer
+   to it then unmaps the page again.  This is almost certainly "undefined"
+   behaviour, but should be good enough for this small test program.  */
+
+static void *
+make_invalid_ptr (void)
+{
+  int page_size, ans;
+  void *ptr;
+  
+  page_size = getpagesize ();
+  ptr =  mmap (0, page_size, PROT_NONE,
+              MAP_PRIVATE | MAP_ANONYMOUS,
+              -1, 0);
+  assert (ptr != MAP_FAILED);
+  ans = munmap (ptr, page_size);
+  assert (ans == 0);
+
+  return ptr;
+}
+
+int 
+main (void)
+{
+  void *invalid_ptr;
+
+  invalid_ptr = make_invalid_ptr ();
+  func1 (invalid_ptr);
+  
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp b/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp
new file mode 100644 (file)
index 0000000..0225326
--- /dev/null
@@ -0,0 +1,111 @@
+# Copyright (C) 2014 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/>.
+
+# In this test we're looking at how gdb handles backtraces and
+# investigating the stack depth when confronted with an "invalid" stack,
+# that is a stack where the first few frames are normal, and then there's a
+# frame where the stack in unreadable.
+#
+# One interesting bug that has been observed is that gdb will sometime
+# exhibit different behaviour the first time a stack command is run
+# compared to the second (and later) times a command is run.  This is
+# because the first time a command is run gdb actually tries to figure out
+# the answer, while the second (and later) times gdb relies on the answer
+# cached from the first time.  As a result in this test each command is
+# run twice, and we restart gdb before testing each different command to
+# ensure that nothing is being cached.
+
+set opts {}
+standard_testfile .c
+
+if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
+    verbose "Skipping ${testfile}."
+    return
+}
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} $opts] } {
+    return -1
+}
+
+if ![runto breakpt] {
+    return -1
+}
+
+# Use 'bt no-filters' here as the python filters will raise their own
+# error during initialisation, the no-filters case is simpler.
+
+gdb_test "bt no-filters" "^bt no-filters\r\n#0 +$hex in func2 \\(\\)\r\nCannot access memory at address 0x\[0-9a-f\]+" \
+        "first backtrace, with error message"
+
+send_gdb "bt no-filters\n"
+gdb_expect {
+    -re "^bt no-filters\r\n#0 +$hex in func2 \\(\\)\r\nCannot access memory at address 0x\[0-9a-f\]+\r\n$gdb_prompt $" {
+       # Currently gdb will not display the error message associated with
+       # the truncated backtrace after the first backtrace has been
+       # completed.  Ideally, we would do this.  If this case is ever hit
+       # then we have started to display the backtrace in all cases and
+       # the xpass should becomd a pass, and the previous pass case below
+       # should be removed, or changed to a fail.
+       xpass "second backtrace, with error message"
+    }
+    -re "^bt no-filters\r\n#0 +$hex in func2 \\(\\)\r\n$gdb_prompt $" {
+       pass "second backtrace, without error message"
+    }
+    timeout {
+       fail "second backtrace (timeout)"
+    }
+}
+
+clean_restart ${binfile}
+
+if ![runto breakpt] {
+    return -1
+}
+
+set test_name "check mi -stack-info-depth command, first time"
+send_gdb "interpreter-exec mi \"-stack-info-depth\"\n"
+gdb_expect {
+    -re "\\^done,depth=\"1\"\r\n$gdb_prompt $" {
+       pass $test_name
+    }
+    -re "\\^error,msg=\"Cannot access memory at address $hex\"\r\n$gdb_prompt $" {
+       xfail $test_name
+    }
+}
+
+gdb_test "interpreter-exec mi \"-stack-info-depth\"" \
+    "\\^done,depth=\"1\"" \
+    "check mi -stack-info-depth command, second time"
+
+clean_restart ${binfile}
+
+if ![runto breakpt] {
+    return -1
+}
+
+set test_name "check mi -stack-list-frames command, first time"
+send_gdb "interpreter-exec mi \"-stack-list-frames\"\n"
+gdb_expect {
+    -re "\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"func2\"\}\\\]\r\n$gdb_prompt $" {
+       pass $test_name
+    }
+    -re "\\^error,msg=\"Cannot access memory at address $hex\"\r\n$gdb_prompt $" {
+       xfail $test_name
+    }
+}
+
+
+gdb_test "interpreter-exec mi \"-stack-list-frames\"" \
+    "\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"func2\"\}\\\]" \
+    "check mi -stack-list-frames command, second time"