This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v3 2/4] Remove previous frame if an error occurs when computing frame id during unwind.


On 16/05/2014 4:37 PM, Pedro Alves wrote:
> On 04/30/2014 11:55 AM, Andrew Burgess wrote:
>> In get_prev_frame_if_no_cycle, if we throw an error during compute_frame_id
>> then we are left in a state where THIS_FRAME has a PREV_FRAME attached, but
>> PREV_FRAME has no frame id.  This is an unexpected state that causes
>> internal errors and assertions to fire.
>>
>> This patch adds a cleanup that removes the previous frame created by
>> get_prev_frame_raw if we get an error.
>>
>> OK to apply?
> 
> This is OK.  Thank you.
> 
> (I guess it could go in immediately if you adjust
> the test to expect the error and only try each command
> once.)

Here's a revised patch that includes some tests, the gdb code hasn't changed
I've merged in the changes you suggested in your review:
  https://sourceware.org/ml/gdb-patches/2014-05/msg00698.html

The only thing that might be controversial is I've added some XFAIL for the
four cases that would be fixed by the later parts of this patch series, I wasn't
planning to raise a bugzilla bug though...

Given that you've OK'd the tests (with fixes) and the code, I'll push this in
a couple of days unless someone objects to my use of XFAIL like this.

Thanks,
Andrew

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/frame.c                                        |   52 +-
 .../gdb.arch/amd64-invalid-stack-middle.S          | 1410 ++++++++++++++++++++
 .../gdb.arch/amd64-invalid-stack-middle.c          |   89 ++
 .../gdb.arch/amd64-invalid-stack-middle.exp        |  108 ++
 gdb/testsuite/gdb.arch/amd64-invalid-stack-top.c   |   73 +
 gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp |  111 ++
 6 files changed, 1829 insertions(+), 14 deletions(-)
 create mode 100644 gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.S
 create mode 100644 gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c
 create mode 100644 gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp
 create mode 100644 gdb/testsuite/gdb.arch/amd64-invalid-stack-top.c
 create mode 100644 gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp

diff --git a/gdb/frame.c b/gdb/frame.c
index 013d602..cbff25f 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -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
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
index 0000000..3b4a067
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.S
@@ -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
index 0000000..05bbd1d
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.c
@@ -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
index 0000000..8ad5b18
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp
@@ -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
index 0000000..168dc55
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.c
@@ -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
index 0000000..0225326
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp
@@ -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"
-- 
1.8.1.3









Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]