From 083940a93df17c6e50d6523e30d56ca3d179f688 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 9 Jul 2017 16:04:02 -0700 Subject: Fix core dump in substitute-object-in-subtree Without this fix, (substitute-object-in-subtree #0=(#0# 'a) 'a) would dump core, since the C code would recurse indefinitely through the infinite structure. This patch adds an argument to the function, and renames it to lread--substitute-object-in-subtree as the function is not general-purpose and should not be relied on by outside code. See Bug#23660. * src/intervals.c (traverse_intervals_noorder): ARG is now void *, not Lisp_Object, so that callers need not cons unnecessarily. All callers changed. Also, remove related #if-0 code that was “temporary” in the early 1990s and has not been compilable for some time. * src/lread.c (struct subst): New type, for substitution closure data. (seen_list): Remove this static var, as this info is now part of struct subst. All uses removed. (Flread__substitute_object_in_subtree): Rename from Fsubstitute_object_in_subtree, and give it a 3rd arg so that it doesn’t dump core when called from the top level with an already-cyclic structure. All callers changed. (SUBSTITUTE): Remove. All callers expanded and then simplified. (substitute_object_recurse): Take a single argument SUBST rather than a pair OBJECT and PLACEHOLDER, so that its address can be passed around as part of a closure; this avoids the need for an AUTO_CONS call. All callers changed. If the COMPLETED component is t, treat every subobject as potentially circular. (substitute_in_interval): Take a struct subst * rather than a Lisp_Object, for the closure data. All callers changed. * test/src/lread-tests.el (lread-lread--substitute-object-in-subtree): New test, to check that the core dump does not reoccur. --- src/alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/alloc.c') diff --git a/src/alloc.c b/src/alloc.c index ac3de83b2b6..2d785d5b9a4 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1553,7 +1553,7 @@ make_interval (void) /* Mark Lisp objects in interval I. */ static void -mark_interval (register INTERVAL i, Lisp_Object dummy) +mark_interval (INTERVAL i, void *dummy) { /* Intervals should never be shared. So, if extra internal checking is enabled, GC aborts if it seems to have visited an interval twice. */ @@ -1567,7 +1567,7 @@ mark_interval (register INTERVAL i, Lisp_Object dummy) #define MARK_INTERVAL_TREE(i) \ do { \ if (i && !i->gcmarkbit) \ - traverse_intervals_noorder (i, mark_interval, Qnil); \ + traverse_intervals_noorder (i, mark_interval, NULL); \ } while (0) /*********************************************************************** -- cgit v1.2.1 From 7a4d9f6304cffa39642507609605bcbfa40d4675 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 25 Jul 2017 01:12:50 +0200 Subject: Properly align global lispsym * lib-src/make-docfile.c (close_emacs_globals): Wrap struct Lisp_Symbols inside struct. * src/alloc.c (sweep_symbols): Update use of lispsym. * src/lisp.h (builtin_lisp_symbol): Likewise. --- src/alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/alloc.c') diff --git a/src/alloc.c b/src/alloc.c index 2d785d5b9a4..2cee6462564 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6943,7 +6943,7 @@ sweep_symbols (void) symbol_free_list = NULL; for (int i = 0; i < ARRAYELTS (lispsym); i++) - lispsym[i].gcmarkbit = 0; + lispsym[i].s.gcmarkbit = 0; for (sblk = symbol_block; sblk; sblk = *sprev) { -- cgit v1.2.1