Blame SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-2of8.patch

01917d
commit 33f8fe58b9a55a0075a90cc9080a1716221a3f81
01917d
Author: Pedro Alves <palves@redhat.com>
01917d
Date:   Fri Nov 22 11:51:59 2013 +0000
01917d
01917d
    Don't let two frames with the same id end up in the frame chain.
01917d
    
01917d
    The UNWIND_SAME_ID check is done between THIS_FRAME and the next frame
01917d
    when we go try to unwind the previous frame.  But at this point, it's
01917d
    already too late -- we ended up with two frames with the same ID in
01917d
    the frame chain.  Each frame having its own ID is an invariant assumed
01917d
    throughout GDB.  This patch applies the UNWIND_SAME_ID detection
01917d
    earlier, right after the previous frame is unwound, discarding the dup
01917d
    frame if a cycle is detected.
01917d
    
01917d
    The patch includes a new test that fails before the change.  Before
01917d
    the patch, the test causes an infinite loop in GDB, after the patch,
01917d
    the UNWIND_SAME_ID logic kicks in and makes the backtrace stop with:
01917d
    
01917d
      Backtrace stopped: previous frame identical to this frame (corrupt stack?)
01917d
    
01917d
    The test uses dwarf CFI to emulate a corrupted stack with a cycle.  It
01917d
    has a function with registers marked DW_CFA_same_value (most
01917d
    importantly RSP/RIP), so that GDB computes the same ID for that frame
01917d
    and its caller.  IOW, something like this:
01917d
    
01917d
     #0 - frame_id_1
01917d
     #1 - frame_id_2
01917d
     #2 - frame_id_3
01917d
     #3 - frame_id_4
01917d
     #4 - frame_id_4  <<<< outermost (UNWIND_SAME_ID).
01917d
    
01917d
    (The test's code is just a copy of dw2-reg-undefined.S /
01917d
    dw2-reg-undefined.c, adjusted to use DW_CFA_same_value instead of
01917d
    DW_CFA_undefined, and to mark a different set of registers.)
01917d
    
01917d
    The infinite loop is here, in value_fetch_lazy:
01917d
    
01917d
          while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val))
01917d
    	{
01917d
    	  frame = frame_find_by_id (VALUE_FRAME_ID (new_val));
01917d
    ...
01917d
    	  new_val = get_frame_register_value (frame, regnum);
01917d
    	}
01917d
    
01917d
    get_frame_register_value can return a lazy register value pointing to
01917d
    the next frame.  This means that the register wasn't clobbered by
01917d
    FRAME; the debugger should therefore retrieve its value from the next
01917d
    frame.
01917d
    
01917d
    To be clear, get_frame_register_value unwinds the value in question
01917d
    from the next frame:
01917d
    
01917d
     struct value *
01917d
     get_frame_register_value (struct frame_info *frame, int regnum)
01917d
     {
01917d
       return frame_unwind_register_value (frame->next, regnum);
01917d
                                           ^^^^^^^^^^^
01917d
     }
01917d
    
01917d
    In other words, if we get a lazy lval_register, it should have the
01917d
    frame ID of the _next_ frame, never of FRAME.
01917d
    
01917d
    At this point in value_fetch_lazy, the whole relevant chunk of the
01917d
    stack up to frame #4 has already been unwound.  The loop always
01917d
    "unlazies" lval_registers in the "next/innermost" direction, not in
01917d
    the "prev/unwind further/outermost" direction.
01917d
    
01917d
    So say we're looking at frame #4.  get_frame_register_value in frame
01917d
    #4 can return a lazy register value of frame #3.  So the next
01917d
    iteration, frame_find_by_id tries to read the register from frame #3.
01917d
    But, since frame #4 happens to have same id as frame #3,
01917d
    frame_find_by_id returns frame #4 instead.  Rinse, repeat, and we have
01917d
    an infinite loop.
01917d
    
01917d
    This is an old latent problem, exposed by the recent addition of the
01917d
    frame stash.  Before we had a stash, frame_find_by_id(frame_id_4)
01917d
    would walk over all frames starting at the current frame, and would
01917d
    always find #3 first.  The stash happens to return #4 instead:
01917d
    
01917d
    struct frame_info *
01917d
    frame_find_by_id (struct frame_id id)
01917d
    {
01917d
      struct frame_info *frame, *prev_frame;
01917d
    
01917d
    ...
01917d
      /* Try using the frame stash first.  Finding it there removes the need
01917d
         to perform the search by looping over all frames, which can be very
01917d
         CPU-intensive if the number of frames is very high (the loop is O(n)
01917d
         and get_prev_frame performs a series of checks that are relatively
01917d
         expensive).  This optimization is particularly useful when this function
01917d
         is called from another function (such as value_fetch_lazy, case
01917d
         VALUE_LVAL (val) == lval_register) which already loops over all frames,
01917d
         making the overall behavior O(n^2).  */
01917d
      frame = frame_stash_find (id);
01917d
      if (frame)
01917d
        return frame;
01917d
    
01917d
      for (frame = get_current_frame (); ; frame = prev_frame)
01917d
        {
01917d
    
01917d
    gdb/
01917d
    2013-11-22  Pedro Alves  <palves@redhat.com>
01917d
    
01917d
    	PR 16155
01917d
    	* frame.c (get_prev_frame_1): Do the UNWIND_SAME_ID check between
01917d
    	this frame and the new previous frame, not between this frame and
01917d
    	the next frame.
01917d
    
01917d
    gdb/testsuite/
01917d
    2013-11-22  Pedro Alves  <palves@redhat.com>
01917d
    
01917d
    	PR 16155
01917d
    	* gdb.dwarf2/dw2-dup-frame.S: New file.
01917d
    	* gdb.dwarf2/dw2-dup-frame.c: New file.
01917d
    	* gdb.dwarf2/dw2-dup-frame.exp: New file.
01917d
01917d
Index: gdb-7.6.1/gdb/frame.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/frame.c
01917d
+++ gdb-7.6.1/gdb/frame.c
01917d
@@ -1689,6 +1689,7 @@ get_prev_frame_1 (struct frame_info *thi
01917d
 {
01917d
   struct frame_id this_id;
01917d
   struct gdbarch *gdbarch;
01917d
+  struct frame_info *prev_frame;
01917d
 
01917d
   gdb_assert (this_frame != NULL);
01917d
   gdbarch = get_frame_arch (this_frame);
01917d
@@ -1790,22 +1791,6 @@ get_prev_frame_1 (struct frame_info *thi
01917d
 	}
01917d
     }
01917d
 
01917d
-  /* Check that this and the next frame are not identical.  If they
01917d
-     are, there is most likely a stack cycle.  As with the inner-than
01917d
-     test above, avoid comparing the inner-most and sentinel frames.  */
01917d
-  if (this_frame->level > 0
01917d
-      && frame_id_eq (this_id, get_frame_id (this_frame->next)))
01917d
-    {
01917d
-      if (frame_debug)
01917d
-	{
01917d
-	  fprintf_unfiltered (gdb_stdlog, "-> ");
01917d
-	  fprint_frame (gdb_stdlog, NULL);
01917d
-	  fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
01917d
-	}
01917d
-      this_frame->stop_reason = UNWIND_SAME_ID;
01917d
-      return NULL;
01917d
-    }
01917d
-
01917d
   /* Check that this and the next frame do not unwind the PC register
01917d
      to the same memory location.  If they do, then even though they
01917d
      have different frame IDs, the new frame will be bogus; two
01917d
@@ -1853,7 +1838,31 @@ get_prev_frame_1 (struct frame_info *thi
01917d
 	}
01917d
     }
01917d
 
01917d
-  return get_prev_frame_raw (this_frame);
01917d
+  prev_frame = get_prev_frame_raw (this_frame);
01917d
+
01917d
+  /* Check that this and the prev frame are not identical.  If they
01917d
+     are, there is most likely a stack cycle.  Unlike the tests above,
01917d
+     we do this right after creating the prev frame, to avoid ever
01917d
+     ending up with two frames with the same id in the frame
01917d
+     chain.  */
01917d
+  if (prev_frame != NULL
01917d
+      && frame_id_eq (get_frame_id (prev_frame),
01917d
+		      get_frame_id (this_frame)))
01917d
+    {
01917d
+      if (frame_debug)
01917d
+	{
01917d
+	  fprintf_unfiltered (gdb_stdlog, "-> ");
01917d
+	  fprint_frame (gdb_stdlog, NULL);
01917d
+	  fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
01917d
+	}
01917d
+      this_frame->stop_reason = UNWIND_SAME_ID;
01917d
+      /* Unlink.  */
01917d
+      prev_frame->next = NULL;
01917d
+      this_frame->prev = NULL;
01917d
+      return NULL;
01917d
+    }
01917d
+
01917d
+  return prev_frame;
01917d
 }
01917d
 
01917d
 /* Construct a new "struct frame_info" and link it previous to
01917d
Index: gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.S
01917d
===================================================================
01917d
--- /dev/null
01917d
+++ gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.S
01917d
@@ -0,0 +1,540 @@
01917d
+/*
01917d
+   Copyright 2013 Free Software Foundation, Inc.
01917d
+
01917d
+   This program is free software; you can redistribute it and/or modify
01917d
+   it under the terms of the GNU General Public License as published by
01917d
+   the Free Software Foundation; either version 3 of the License, or
01917d
+   (at your option) any later version.
01917d
+
01917d
+   This program is distributed in the hope that it will be useful,
01917d
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
01917d
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
01917d
+   GNU General Public License for more details.
01917d
+
01917d
+   You should have received a copy of the GNU General Public License
01917d
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
01917d
+
01917d
+	/* The FDE entry for "stop_frame" in the .debug_frame section has
01917d
+	been hand modified to mark a set of registers as DW_CFA_same_value.
01917d
+	Otherwise this file is as generated by gcc 4.7.2 for x86_64.  */
01917d
+	.file	"dw2-dup-frame.c"
01917d
+	.text
01917d
+.Ltext0:
01917d
+	.globl	stop_frame
01917d
+	.type	stop_frame, @function
01917d
+stop_frame:
01917d
+.LFB0:
01917d
+	.file 1 "dw2-dup-frame.c"
01917d
+	.loc 1 19 0
01917d
+	pushq	%rbp
01917d
+.LCFI0:
01917d
+	movq	%rsp, %rbp
01917d
+.LCFI1:
01917d
+	.loc 1 22 0
01917d
+	popq	%rbp
01917d
+.LCFI2:
01917d
+	ret
01917d
+.LFE0:
01917d
+	.size	stop_frame, .-stop_frame
01917d
+	.globl	first_frame
01917d
+	.type	first_frame, @function
01917d
+first_frame:
01917d
+.LFB1:
01917d
+	.loc 1 26 0
01917d
+	pushq	%rbp
01917d
+.LCFI3:
01917d
+	movq	%rsp, %rbp
01917d
+.LCFI4:
01917d
+	.loc 1 27 0
01917d
+	movl	$0, %eax
01917d
+	call	stop_frame
01917d
+	.loc 1 28 0
01917d
+	popq	%rbp
01917d
+.LCFI5:
01917d
+	ret
01917d
+.LFE1:
01917d
+	.size	first_frame, .-first_frame
01917d
+	.globl	main
01917d
+	.type	main, @function
01917d
+main:
01917d
+.LFB2:
01917d
+	.loc 1 32 0
01917d
+	pushq	%rbp
01917d
+.LCFI6:
01917d
+	movq	%rsp, %rbp
01917d
+.LCFI7:
01917d
+	.loc 1 33 0
01917d
+	movl	$0, %eax
01917d
+	call	first_frame
01917d
+	.loc 1 35 0
01917d
+	movl	$0, %eax
01917d
+	.loc 1 36 0
01917d
+	popq	%rbp
01917d
+.LCFI8:
01917d
+	ret
01917d
+.LFE2:
01917d
+	.size	main, .-main
01917d
+	.section	.debug_frame,"",@progbits
01917d
+.Lframe0:
01917d
+	.long	.LECIE0-.LSCIE0
01917d
+.LSCIE0:
01917d
+	.long	0xffffffff
01917d
+	.byte	0x1
01917d
+	.string	""
01917d
+	.uleb128 0x1
01917d
+	.sleb128 -8
01917d
+	.byte	0x10
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.byte	0x90
01917d
+	.uleb128 0x1
01917d
+	.align 8
01917d
+.LECIE0:
01917d
+	/* This FDE entry, for stop_frame was modified to mark
01917d
+	   registers 0 -> 16 (rax..ra/rip) as being DW_CFA_same_value.  */
01917d
+.LSFDE0:
01917d
+	.long	.LEFDE0-.LASFDE0
01917d
+.LASFDE0:
01917d
+	.long	.Lframe0
01917d
+	.quad	.LFB0
01917d
+	.quad	.LFE0-.LFB0
01917d
+
01917d
+		/* START OF NEW CONTENT.  */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x0			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x1			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x2			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x3			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x4			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x5			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x6			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x7			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x8			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x9			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0xa			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0xb			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0xc			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0xd			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0xe			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0xf			/*   ULEB128 register */
01917d
+	.byte	0x8			/* DW_CFA_same_value */
01917d
+	.uleb128 0x10			 /*   ULEB128 register */
01917d
+		/* END OF NEW CONTENT.  */
01917d
+
01917d
+	.byte	0x4
01917d
+	.long	.LCFI0-.LFB0
01917d
+	.byte	0xe
01917d
+	.uleb128 0x10
01917d
+	.byte	0x86
01917d
+	.uleb128 0x2
01917d
+	.byte	0x4
01917d
+	.long	.LCFI1-.LCFI0
01917d
+	.byte	0xd
01917d
+	.uleb128 0x6
01917d
+	.byte	0x4
01917d
+	.long	.LCFI2-.LCFI1
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.align 8
01917d
+.LEFDE0:
01917d
+.LSFDE2:
01917d
+	.long	.LEFDE2-.LASFDE2
01917d
+.LASFDE2:
01917d
+	.long	.Lframe0
01917d
+	.quad	.LFB1
01917d
+	.quad	.LFE1-.LFB1
01917d
+	.byte	0x4
01917d
+	.long	.LCFI3-.LFB1
01917d
+	.byte	0xe
01917d
+	.uleb128 0x10
01917d
+	.byte	0x86
01917d
+	.uleb128 0x2
01917d
+	.byte	0x4
01917d
+	.long	.LCFI4-.LCFI3
01917d
+	.byte	0xd
01917d
+	.uleb128 0x6
01917d
+	.byte	0x4
01917d
+	.long	.LCFI5-.LCFI4
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.align 8
01917d
+.LEFDE2:
01917d
+.LSFDE4:
01917d
+	.long	.LEFDE4-.LASFDE4
01917d
+.LASFDE4:
01917d
+	.long	.Lframe0
01917d
+	.quad	.LFB2
01917d
+	.quad	.LFE2-.LFB2
01917d
+	.byte	0x4
01917d
+	.long	.LCFI6-.LFB2
01917d
+	.byte	0xe
01917d
+	.uleb128 0x10
01917d
+	.byte	0x86
01917d
+	.uleb128 0x2
01917d
+	.byte	0x4
01917d
+	.long	.LCFI7-.LCFI6
01917d
+	.byte	0xd
01917d
+	.uleb128 0x6
01917d
+	.byte	0x4
01917d
+	.long	.LCFI8-.LCFI7
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.align 8
01917d
+.LEFDE4:
01917d
+	.section	.eh_frame,"a",@progbits
01917d
+.Lframe1:
01917d
+	.long	.LECIE1-.LSCIE1
01917d
+.LSCIE1:
01917d
+	.long	0
01917d
+	.byte	0x1
01917d
+	.string	"zR"
01917d
+	.uleb128 0x1
01917d
+	.sleb128 -8
01917d
+	.byte	0x10
01917d
+	.uleb128 0x1
01917d
+	.byte	0x3
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.byte	0x90
01917d
+	.uleb128 0x1
01917d
+	.align 8
01917d
+.LECIE1:
01917d
+.LSFDE7:
01917d
+	.long	.LEFDE7-.LASFDE7
01917d
+.LASFDE7:
01917d
+	.long	.LASFDE7-.Lframe1
01917d
+	.long	.LFB0
01917d
+	.long	.LFE0-.LFB0
01917d
+	.uleb128 0
01917d
+	.byte	0x4
01917d
+	.long	.LCFI0-.LFB0
01917d
+	.byte	0xe
01917d
+	.uleb128 0x10
01917d
+	.byte	0x86
01917d
+	.uleb128 0x2
01917d
+	.byte	0x4
01917d
+	.long	.LCFI1-.LCFI0
01917d
+	.byte	0xd
01917d
+	.uleb128 0x6
01917d
+	.byte	0x4
01917d
+	.long	.LCFI2-.LCFI1
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.align 8
01917d
+.LEFDE7:
01917d
+.LSFDE9:
01917d
+	.long	.LEFDE9-.LASFDE9
01917d
+.LASFDE9:
01917d
+	.long	.LASFDE9-.Lframe1
01917d
+	.long	.LFB1
01917d
+	.long	.LFE1-.LFB1
01917d
+	.uleb128 0
01917d
+	.byte	0x4
01917d
+	.long	.LCFI3-.LFB1
01917d
+	.byte	0xe
01917d
+	.uleb128 0x10
01917d
+	.byte	0x86
01917d
+	.uleb128 0x2
01917d
+	.byte	0x4
01917d
+	.long	.LCFI4-.LCFI3
01917d
+	.byte	0xd
01917d
+	.uleb128 0x6
01917d
+	.byte	0x4
01917d
+	.long	.LCFI5-.LCFI4
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.align 8
01917d
+.LEFDE9:
01917d
+.LSFDE11:
01917d
+	.long	.LEFDE11-.LASFDE11
01917d
+.LASFDE11:
01917d
+	.long	.LASFDE11-.Lframe1
01917d
+	.long	.LFB2
01917d
+	.long	.LFE2-.LFB2
01917d
+	.uleb128 0
01917d
+	.byte	0x4
01917d
+	.long	.LCFI6-.LFB2
01917d
+	.byte	0xe
01917d
+	.uleb128 0x10
01917d
+	.byte	0x86
01917d
+	.uleb128 0x2
01917d
+	.byte	0x4
01917d
+	.long	.LCFI7-.LCFI6
01917d
+	.byte	0xd
01917d
+	.uleb128 0x6
01917d
+	.byte	0x4
01917d
+	.long	.LCFI8-.LCFI7
01917d
+	.byte	0xc
01917d
+	.uleb128 0x7
01917d
+	.uleb128 0x8
01917d
+	.align 8
01917d
+.LEFDE11:
01917d
+	.text
01917d
+.Letext0:
01917d
+	.section	.debug_info,"",@progbits
01917d
+.Ldebug_info0:
01917d
+	.long	0x8c
01917d
+	.value	0x2
01917d
+	.long	.Ldebug_abbrev0
01917d
+	.byte	0x8
01917d
+	.uleb128 0x1
01917d
+	.long	.LASF2
01917d
+	.byte	0x1
01917d
+	.long	.LASF3
01917d
+	.long	.LASF4
01917d
+	.quad	.Ltext0
01917d
+	.quad	.Letext0
01917d
+	.long	.Ldebug_line0
01917d
+	.uleb128 0x2
01917d
+	.byte	0x1
01917d
+	.long	.LASF0
01917d
+	.byte	0x1
01917d
+	.byte	0x12
01917d
+	.quad	.LFB0
01917d
+	.quad	.LFE0
01917d
+	.long	.LLST0
01917d
+	.byte	0x1
01917d
+	.uleb128 0x3
01917d
+	.byte	0x1
01917d
+	.long	.LASF1
01917d
+	.byte	0x1
01917d
+	.byte	0x19
01917d
+	.quad	.LFB1
01917d
+	.quad	.LFE1
01917d
+	.long	.LLST1
01917d
+	.byte	0x1
01917d
+	.uleb128 0x4
01917d
+	.byte	0x1
01917d
+	.long	.LASF5
01917d
+	.byte	0x1
01917d
+	.byte	0x1f
01917d
+	.long	0x88
01917d
+	.quad	.LFB2
01917d
+	.quad	.LFE2
01917d
+	.long	.LLST2
01917d
+	.byte	0x1
01917d
+	.uleb128 0x5
01917d
+	.byte	0x4
01917d
+	.byte	0x5
01917d
+	.string	"int"
01917d
+	.byte	0
01917d
+	.section	.debug_abbrev,"",@progbits
01917d
+.Ldebug_abbrev0:
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x11
01917d
+	.byte	0x1
01917d
+	.uleb128 0x25
01917d
+	.uleb128 0xe
01917d
+	.uleb128 0x13
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x3
01917d
+	.uleb128 0xe
01917d
+	.uleb128 0x1b
01917d
+	.uleb128 0xe
01917d
+	.uleb128 0x11
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x12
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x10
01917d
+	.uleb128 0x6
01917d
+	.byte	0
01917d
+	.byte	0
01917d
+	.uleb128 0x2
01917d
+	.uleb128 0x2e
01917d
+	.byte	0
01917d
+	.uleb128 0x3f
01917d
+	.uleb128 0xc
01917d
+	.uleb128 0x3
01917d
+	.uleb128 0xe
01917d
+	.uleb128 0x3a
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x3b
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x11
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x12
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x40
01917d
+	.uleb128 0x6
01917d
+	.uleb128 0x2117
01917d
+	.uleb128 0xc
01917d
+	.byte	0
01917d
+	.byte	0
01917d
+	.uleb128 0x3
01917d
+	.uleb128 0x2e
01917d
+	.byte	0
01917d
+	.uleb128 0x3f
01917d
+	.uleb128 0xc
01917d
+	.uleb128 0x3
01917d
+	.uleb128 0xe
01917d
+	.uleb128 0x3a
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x3b
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x11
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x12
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x40
01917d
+	.uleb128 0x6
01917d
+	.uleb128 0x2116
01917d
+	.uleb128 0xc
01917d
+	.byte	0
01917d
+	.byte	0
01917d
+	.uleb128 0x4
01917d
+	.uleb128 0x2e
01917d
+	.byte	0
01917d
+	.uleb128 0x3f
01917d
+	.uleb128 0xc
01917d
+	.uleb128 0x3
01917d
+	.uleb128 0xe
01917d
+	.uleb128 0x3a
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x3b
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x49
01917d
+	.uleb128 0x13
01917d
+	.uleb128 0x11
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x12
01917d
+	.uleb128 0x1
01917d
+	.uleb128 0x40
01917d
+	.uleb128 0x6
01917d
+	.uleb128 0x2116
01917d
+	.uleb128 0xc
01917d
+	.byte	0
01917d
+	.byte	0
01917d
+	.uleb128 0x5
01917d
+	.uleb128 0x24
01917d
+	.byte	0
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x3e
01917d
+	.uleb128 0xb
01917d
+	.uleb128 0x3
01917d
+	.uleb128 0x8
01917d
+	.byte	0
01917d
+	.byte	0
01917d
+	.byte	0
01917d
+	.section	.debug_loc,"",@progbits
01917d
+.Ldebug_loc0:
01917d
+.LLST0:
01917d
+	.quad	.LFB0-.Ltext0
01917d
+	.quad	.LCFI0-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 8
01917d
+	.quad	.LCFI0-.Ltext0
01917d
+	.quad	.LCFI1-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 16
01917d
+	.quad	.LCFI1-.Ltext0
01917d
+	.quad	.LCFI2-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x76
01917d
+	.sleb128 16
01917d
+	.quad	.LCFI2-.Ltext0
01917d
+	.quad	.LFE0-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 8
01917d
+	.quad	0
01917d
+	.quad	0
01917d
+.LLST1:
01917d
+	.quad	.LFB1-.Ltext0
01917d
+	.quad	.LCFI3-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 8
01917d
+	.quad	.LCFI3-.Ltext0
01917d
+	.quad	.LCFI4-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 16
01917d
+	.quad	.LCFI4-.Ltext0
01917d
+	.quad	.LCFI5-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x76
01917d
+	.sleb128 16
01917d
+	.quad	.LCFI5-.Ltext0
01917d
+	.quad	.LFE1-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 8
01917d
+	.quad	0
01917d
+	.quad	0
01917d
+.LLST2:
01917d
+	.quad	.LFB2-.Ltext0
01917d
+	.quad	.LCFI6-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 8
01917d
+	.quad	.LCFI6-.Ltext0
01917d
+	.quad	.LCFI7-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 16
01917d
+	.quad	.LCFI7-.Ltext0
01917d
+	.quad	.LCFI8-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x76
01917d
+	.sleb128 16
01917d
+	.quad	.LCFI8-.Ltext0
01917d
+	.quad	.LFE2-.Ltext0
01917d
+	.value	0x2
01917d
+	.byte	0x77
01917d
+	.sleb128 8
01917d
+	.quad	0
01917d
+	.quad	0
01917d
+	.section	.debug_aranges,"",@progbits
01917d
+	.long	0x2c
01917d
+	.value	0x2
01917d
+	.long	.Ldebug_info0
01917d
+	.byte	0x8
01917d
+	.byte	0
01917d
+	.value	0
01917d
+	.value	0
01917d
+	.quad	.Ltext0
01917d
+	.quad	.Letext0-.Ltext0
01917d
+	.quad	0
01917d
+	.quad	0
01917d
+	.section	.debug_line,"",@progbits
01917d
+.Ldebug_line0:
01917d
+	.section	.debug_str,"MS",@progbits,1
01917d
+.LASF0:
01917d
+	.string	"stop_frame"
01917d
+.LASF3:
01917d
+	.string	"dw2-reg-undefined.c"
01917d
+.LASF2:
01917d
+	.string	"GNU C 4.7.2"
01917d
+.LASF1:
01917d
+	.string	"first_frame"
01917d
+.LASF5:
01917d
+	.string	"main"
01917d
+.LASF4:
01917d
+	.string	"/home/username/src/gdb/testsuite/gdb.dwarf2"
01917d
+	.ident	"GCC: (GNU) 4.7.2"
01917d
+	.section	.note.GNU-stack,"",@progbits
01917d
Index: gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.c
01917d
===================================================================
01917d
--- /dev/null
01917d
+++ gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.c
01917d
@@ -0,0 +1,36 @@
01917d
+/*
01917d
+   Copyright 2013 Free Software Foundation, Inc.
01917d
+
01917d
+   This program is free software; you can redistribute it and/or modify
01917d
+   it under the terms of the GNU General Public License as published by
01917d
+   the Free Software Foundation; either version 3 of the License, or
01917d
+   (at your option) any later version.
01917d
+
01917d
+   This program is distributed in the hope that it will be useful,
01917d
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
01917d
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
01917d
+   GNU General Public License for more details.
01917d
+
01917d
+   You should have received a copy of the GNU General Public License
01917d
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
01917d
+
01917d
+void
01917d
+stop_frame ()
01917d
+{
01917d
+  /* The debug information for this frame is modified in the accompanying
01917d
+     .S file, to mark a set of registers as being DW_CFA_same_value.  */
01917d
+}
01917d
+
01917d
+void
01917d
+first_frame ()
01917d
+{
01917d
+  stop_frame ();
01917d
+}
01917d
+
01917d
+int
01917d
+main ()
01917d
+{
01917d
+  first_frame ();
01917d
+
01917d
+  return 0;
01917d
+}
01917d
Index: gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.exp
01917d
===================================================================
01917d
--- /dev/null
01917d
+++ gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.exp
01917d
@@ -0,0 +1,44 @@
01917d
+# Copyright 2013 Free Software Foundation, Inc.
01917d
+
01917d
+# This program is free software; you can redistribute it and/or modify
01917d
+# it under the terms of the GNU General Public License as published by
01917d
+# the Free Software Foundation; either version 3 of the License, or
01917d
+# (at your option) any later version.
01917d
+#
01917d
+# This program is distributed in the hope that it will be useful,
01917d
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
01917d
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
01917d
+# GNU General Public License for more details.
01917d
+#
01917d
+# You should have received a copy of the GNU General Public License
01917d
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
01917d
+load_lib dwarf.exp
01917d
+
01917d
+# This test can only be run on targets which support DWARF-2 and use gas.
01917d
+if {![dwarf2_support]} {
01917d
+    return 0
01917d
+}
01917d
+
01917d
+# This test can only be run on x86_64 targets.
01917d
+if {![istarget "x86_64-*-*"] || ![is_lp64_target]} {
01917d
+    return 0
01917d
+}
01917d
+
01917d
+standard_testfile .S
01917d
+
01917d
+if { [prepare_for_testing $testfile.exp $testfile $srcfile {nodebug}] } {
01917d
+    return -1
01917d
+}
01917d
+
01917d
+if ![runto stop_frame] {
01917d
+    perror "Failed to stop in stop_frame"
01917d
+    return -1
01917d
+}
01917d
+
01917d
+gdb_test "bt" \
01917d
+    "#0  stop_frame \[^\r\n\]*\r\nBacktrace stopped: previous frame identical to this frame \\(corrupt stack\\?\\)" \
01917d
+    "backtrace from stop_frame"
01917d
+
01917d
+gdb_test "up" \
01917d
+    "Initial frame selected; you cannot go up\\\." \
01917d
+    "up from stop_frame"