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

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