diff options
author | Glenn Morris <rgm@gnu.org> | 2012-08-28 09:01:59 -0700 |
---|---|---|
committer | Glenn Morris <rgm@gnu.org> | 2012-08-28 09:01:59 -0700 |
commit | eada086196ccb005ded188ac2e58d41f3682a125 (patch) | |
tree | f195bbf91841ea4e85d465307d62c709924892c2 /src | |
parent | 37b9743e79bac608a45fade0744248446aaa0a33 (diff) | |
parent | 806f0cc7302bd1dacfad8366f67a97e9bfbc8fc9 (diff) | |
download | emacs-eada086196ccb005ded188ac2e58d41f3682a125.tar.gz emacs-eada086196ccb005ded188ac2e58d41f3682a125.tar.bz2 emacs-eada086196ccb005ded188ac2e58d41f3682a125.zip |
Merge from emacs-24; up to 2012-05-04T19:17:01Z!monnier@iro.umontreal.ca
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 9 | ||||
-rw-r--r-- | src/eval.c | 9 | ||||
-rw-r--r-- | src/ralloc.c | 45 |
3 files changed, 45 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2521ddc4144..5bafa1a04f8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-08-28 Eli Zaretskii <eliz@gnu.org> + + * ralloc.c (free_bloc): Don't dereference a 'heap' structure if it + is not one of the heaps we manage. (Bug#12242) + +2012-08-28 Glenn Morris <rgm@gnu.org> + + * eval.c (Fcalled_interactively_p): Doc fix. (Bug#11747) + 2012-08-28 Martin Rudalics <rudalics@gmx.at> * window.c (Fset_window_configuration): Remove handling of diff --git a/src/eval.c b/src/eval.c index df44c87dc25..c56be10c5a0 100644 --- a/src/eval.c +++ b/src/eval.c @@ -544,11 +544,10 @@ thinking of using it for any other purpose, it is quite likely that you're making a mistake. Think: what do you want to do when the command is called from a keyboard macro? -This function is meant for implementing advice and other -function-modifying features. Instead of using this, it is sometimes -cleaner to give your function an extra optional argument whose -`interactive' spec specifies non-nil unconditionally (\"p\" is a good -way to do this), or via (not (or executing-kbd-macro noninteractive)). */) +Instead of using this function, it is sometimes cleaner to give your +function an extra optional argument whose `interactive' spec specifies +non-nil unconditionally (\"p\" is a good way to do this), or via +\(not (or executing-kbd-macro noninteractive)). */) (Lisp_Object kind) { return ((INTERACTIVE || !EQ (kind, intern ("interactive"))) diff --git a/src/ralloc.c b/src/ralloc.c index c40258693f5..3877e21d4f6 100644 --- a/src/ralloc.c +++ b/src/ralloc.c @@ -670,6 +670,7 @@ static void free_bloc (bloc_ptr bloc) { heap_ptr heap = bloc->heap; + heap_ptr h; if (r_alloc_freeze_level) { @@ -699,20 +700,38 @@ free_bloc (bloc_ptr bloc) bloc->prev->next = bloc->next; } - /* Update the records of which blocs are in HEAP. */ - if (heap->first_bloc == bloc) + /* Sometimes, 'heap' obtained from bloc->heap above is not really a + 'heap' structure. It can even be beyond the current break point, + which will cause crashes when we dereference it below (see + bug#12242). Evidently, the reason is bloc allocations done while + use_relocatable_buffers was non-positive, because additional + memory we get then is not recorded in the heaps we manage. If + bloc->heap records such a "heap", we cannot (and don't need to) + update its records. So we validate the 'heap' value by making + sure it is one of the heaps we manage via the heaps linked list, + and don't touch a 'heap' that isn't found there. This avoids + accessing memory we know nothing about. */ + for (h = first_heap; h != NIL_HEAP; h = h->next) + if (heap == h) + break; + + if (h) { - if (bloc->next != 0 && bloc->next->heap == heap) - heap->first_bloc = bloc->next; - else - heap->first_bloc = heap->last_bloc = NIL_BLOC; - } - if (heap->last_bloc == bloc) - { - if (bloc->prev != 0 && bloc->prev->heap == heap) - heap->last_bloc = bloc->prev; - else - heap->first_bloc = heap->last_bloc = NIL_BLOC; + /* Update the records of which blocs are in HEAP. */ + if (heap->first_bloc == bloc) + { + if (bloc->next != 0 && bloc->next->heap == heap) + heap->first_bloc = bloc->next; + else + heap->first_bloc = heap->last_bloc = NIL_BLOC; + } + if (heap->last_bloc == bloc) + { + if (bloc->prev != 0 && bloc->prev->heap == heap) + heap->last_bloc = bloc->prev; + else + heap->first_bloc = heap->last_bloc = NIL_BLOC; + } } relinquish (); |