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:
parent
a9a3835c26
commit
508f51f5f4
2 changed files with 23 additions and 17 deletions
|
@ -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
|
||||
|
|
34
src/ralloc.c
34
src/ralloc.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue