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

01917d
commit 6eeee81c8e59511962bdd83df5e7785bfdf871d2
01917d
Author: Tom Tromey <tromey@redhat.com>
01917d
Date:   Fri Nov 22 17:38:44 2013 +0000
01917d
01917d
    Detect infinite loop in value_fetch_lazy's lval_register handling.
01917d
    
01917d
    If value_fetch_lazy loops infinitely while unwrapping lval_register
01917d
    values, it means we either somehow ended up with two frames with the
01917d
    same ID in the frame chain, or some code is trying to unwind behind
01917d
    get_prev_frame's back (e.g., a frame unwind sniffer trying to unwind).
01917d
    In any case, it should always be an internal error to end up in this
01917d
    situation.
01917d
    
01917d
    This patch adds a check and throws an internal error if the same frame
01917d
    is returned.
01917d
    
01917d
    2013-11-22  Tom Tromey  <tromey@redhat.com>
01917d
    	    Pedro Alves  <palves@redhat.com>
01917d
    
01917d
    	PR backtrace/16155
01917d
    	* value.c (value_fetch_lazy): Internal error if
01917d
    	get_frame_register_value returns the same register.
01917d
01917d
Index: gdb-7.6.1/gdb/valops.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/valops.c
01917d
+++ gdb-7.6.1/gdb/valops.c
01917d
@@ -1093,7 +1093,9 @@ value_fetch_lazy (struct value *val)
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
+	  struct frame_id frame_id = VALUE_FRAME_ID (new_val);
01917d
+
01917d
+	  frame = frame_find_by_id (frame_id);
01917d
 	  regnum = VALUE_REGNUM (new_val);
01917d
 
01917d
 	  gdb_assert (frame != NULL);
01917d
@@ -1107,6 +1109,22 @@ value_fetch_lazy (struct value *val)
01917d
 						   regnum, type));
01917d
 
01917d
 	  new_val = get_frame_register_value (frame, regnum);
01917d
+
01917d
+	  /* If we get another lazy lval_register value, it means the
01917d
+	     register is found by reading it from the next frame.
01917d
+	     get_frame_register_value should never return a value with
01917d
+	     the frame id pointing to FRAME.  If it does, it means we
01917d
+	     either have two consecutive frames with the same frame id
01917d
+	     in the frame chain, or some code is trying to unwind
01917d
+	     behind get_prev_frame's back (e.g., a frame unwind
01917d
+	     sniffer trying to unwind), bypassing its validations.  In
01917d
+	     any case, it should always be an internal error to end up
01917d
+	     in this situation.  */
01917d
+	  if (VALUE_LVAL (new_val) == lval_register
01917d
+	      && value_lazy (new_val)
01917d
+	      && frame_id_eq (VALUE_FRAME_ID (new_val), frame_id))
01917d
+	    internal_error (__FILE__, __LINE__,
01917d
+			    _("infinite loop while fetching a register"));
01917d
 	}
01917d
 
01917d
       /* If it's still lazy (for instance, a saved register on the