PATCH: libgcc2/frame.c more malloc protection

Nathan Sidwell nathan@acm.org
Mon Nov 29 02:52:00 GMT 1999


Hi,

One more patch for frame.c.

execute_cfa_insn is modified to check malloc succeeded in
DW_CFA_remember_state. And commented to the effect that
DW_CFA_remember_state is a bad thing.

__frame_state_for checks that execute_cfa_insn returned an instruction,
and unwinds any state stack to avoid a memory leak.

The three patches for frame.c clean up its heap allocation, which
previously could require large amounts of heap space. Throwing bad_alloc
will still fail due to other difficulties within libgcc2.c, separate
patches forthcoming for that.

ok?

nathan
-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
Never hand someone a gun unless you are sure where they will point it
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
1999-11-29  Nathan Sidwell  <nathan@acm.org>

	* frame.c (execute_cfa_insn): Check malloc for DW_CFA_remember_state.
	(__frame_state_for): Check execute_cfa_insn returns an insn. Free any
	saved state.

Index: frame.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/frame.c,v
retrieving revision 1.26
diff -c -3 -p -r1.26 frame.c
*** frame.c	1999/10/05 19:41:35	1.26
--- frame.c	1999/11/29 10:40:31
*************** execute_cfa_insn (void *p, struct frame_
*** 692,702 ****
--- 692,707 ----
        state->s.cfa_offset = offset;
        break;
        
+       /* remember_state adds unbounded runtime memory requirement. This is
+          fatal for exception handling. GCC doesn't currently emit these. If
+          it ever does exception unwind tables will be broken. */
      case DW_CFA_remember_state:
        {
  	struct frame_state_internal *save =
  	  (struct frame_state_internal *)
  	  malloc (sizeof (struct frame_state_internal));
+ 	if (! save)
+ 	  return NULL;
  	memcpy (save, state, sizeof (struct frame_state_internal));
  	state->saved_state = save;
        }
*************** __frame_state_for (void *pc_target, stru
*** 849,855 ****
  
    /* First decode all the insns in the CIE.  */
    end = next_fde ((fde*) get_cie (f));
!   while (insn < end)
      insn = execute_cfa_insn (insn, &state, &info, 0);
  
    insn = ((fde *)f) + 1;
--- 854,860 ----
  
    /* First decode all the insns in the CIE.  */
    end = next_fde ((fde*) get_cie (f));
!   while (insn != 0 && insn < end)
      insn = execute_cfa_insn (insn, &state, &info, 0);
  
    insn = ((fde *)f) + 1;
*************** __frame_state_for (void *pc_target, stru
*** 864,873 ****
    /* Then the insns in the FDE up to our target PC.  */
    end = next_fde (f);
    pc = f->pc_begin;
!   while (insn < end && pc <= pc_target)
      insn = execute_cfa_insn (insn, &state, &info, &pc);
  
    memcpy (state_in, &state.s, sizeof (state.s));
    return state_in;
  }
  #endif /* DWARF2_UNWIND_INFO */
--- 869,888 ----
    /* Then the insns in the FDE up to our target PC.  */
    end = next_fde (f);
    pc = f->pc_begin;
!   while (insn != 0 && insn < end && pc <= pc_target)
      insn = execute_cfa_insn (insn, &state, &info, &pc);
  
    memcpy (state_in, &state.s, sizeof (state.s));
+   
+   while (state.saved_state != 0)
+     {
+       struct frame_state_internal *saved = state.saved_state;
+       state.saved_state = saved->saved_state;
+       free (saved);
+     }
+   
+   if (insn == 0)
+     return NULL;
    return state_in;
  }
  #endif /* DWARF2_UNWIND_INFO */


More information about the Gcc-patches mailing list