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