summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGlenn Morris <rgm@gnu.org>2012-08-28 09:01:59 -0700
committerGlenn Morris <rgm@gnu.org>2012-08-28 09:01:59 -0700
commiteada086196ccb005ded188ac2e58d41f3682a125 (patch)
treef195bbf91841ea4e85d465307d62c709924892c2 /src
parent37b9743e79bac608a45fade0744248446aaa0a33 (diff)
parent806f0cc7302bd1dacfad8366f67a97e9bfbc8fc9 (diff)
downloademacs-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/ChangeLog9
-rw-r--r--src/eval.c9
-rw-r--r--src/ralloc.c45
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 ();