Fix bug #12774 with crashes in ralloc.c.

src/ralloc.c (relinquish): If real_morecore fails to return memory
 to the system, don't crash; instead, leave the last heap
 unchanged and return.
This commit is contained in:
Eli Zaretskii 2012-11-05 19:23:25 +02:00
parent a9a3835c26
commit 508f51f5f4
2 changed files with 23 additions and 17 deletions

View file

@ -1,3 +1,9 @@
2012-11-05 Eli Zaretskii <eliz@gnu.org>
* ralloc.c (relinquish): If real_morecore fails to return memory
to the system, don't crash; instead, leave the last heap
unchanged and return. (Bug#12774)
2012-11-03 Eli Zaretskii <eliz@gnu.org>
* lisp.mk: Adjust comments to the fact that term/internal is now

View file

@ -327,6 +327,8 @@ relinquish (void)
if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess)
{
heap_ptr lh_prev;
/* This heap should have no blocs in it. If it does, we
cannot return it to the system. */
if (last_heap->first_bloc != NIL_BLOC
@ -335,28 +337,26 @@ relinquish (void)
/* Return the last heap, with its header, to the system. */
excess = (char *)last_heap->end - (char *)last_heap->start;
last_heap = last_heap->prev;
last_heap->next = NIL_HEAP;
lh_prev = last_heap->prev;
/* If the system doesn't want that much memory back, leave
last_heap unaltered to reflect that. This can occur if
break_value is still within the original data segment. */
if ((*real_morecore) (- excess) != 0)
{
last_heap = lh_prev;
last_heap->next = NIL_HEAP;
}
}
else
{
excess = (char *) last_heap->end
- (char *) ROUNDUP ((char *)last_heap->end - excess);
last_heap->end = (char *) last_heap->end - excess;
}
if ((*real_morecore) (- excess) == 0)
{
/* If the system didn't want that much memory back, adjust
the end of the last heap to reflect that. This can occur
if break_value is still within the original data segment. */
last_heap->end = (char *) last_heap->end + excess;
/* Make sure that the result of the adjustment is accurate.
It should be, for the else clause above; the other case,
which returns the entire last heap to the system, seems
unlikely to trigger this mode of failure. */
if (last_heap->end != (*real_morecore) (0))
emacs_abort ();
/* If the system doesn't want that much memory back, leave
the end of the last heap unchanged to reflect that. This
can occur if break_value is still within the original
data segment. */
if ((*real_morecore) (- excess) != 0)
last_heap->end = (char *) last_heap->end - excess;
}
}
}