Subject: bug#42832: 28.0.50; "Bus error" when compiling Emacs now on Debian bullseye

From: Pip Cet <[email-masked]>
Date: Fri, 14 Aug 2020 19:08:56 +0000

On Fri, Aug 14, 2020 at 3:37 PM Lars Ingebrigtsen <[email-masked]> wrote:
> Pip Cet <[email-masked]> writes:
> > I've gone with the last idea. This patch should fix things,
> It does!  With that patch, I'm not able to reproduce the bug.

Oops. There was a bug in the patch which would have resulted in assert
failures had I tested it with assertions. Fixed version attached.

The crash was looking at a hash table created, most likely, by
cl--generic-get-dispatcher; so that makes my theory sound more
plausible, too.
From e9b53aa1c6cdfb8f31bb9de76ae1aa20659752f1 Mon Sep 17 00:00:00 2001
From: Pip Cet <[email-masked]>
Date: Fri, 14 Aug 2020 14:56:19 +0000
Subject: [PATCH] Try to avoid marking zombie pdumper objects.

---
 src/pdumper.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/pdumper.c b/src/pdumper.c
index bc41afc7c5..c05b88ea6d 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -4871,6 +4871,8 @@ dump_bitset_clear (struct dump_bitset *bitset)
   struct dump_header header;
   /* Mark bits for objects in the dump; used during GC.  */
   struct dump_bitset mark_bits;
+  /* Mark bits for objects in the dump; used during GC.  */
+  struct dump_bitset last_mark_bits;
   /* Time taken to load the dump.  */
   double load_time;
   /* Dump file name.  */
@@ -4995,6 +4997,10 @@ pdumper_find_object_type_impl (const void *obj)
     return PDUMPER_NO_OBJECT;
   const struct dump_reloc *reloc =
     dump_find_relocation (&dump_private.header.object_starts, offset);
+  ptrdiff_t bitno = offset / DUMP_ALIGNMENT;
+  if (offset < dump_private.header.cold_start
+      && !dump_bitset_bit_set_p (&dump_private.last_mark_bits, bitno))
+    return PDUMPER_NO_OBJECT;
   return (reloc != NULL && dump_reloc_get_offset (*reloc) == offset)
     ? reloc->type
     : PDUMPER_NO_OBJECT;
@@ -5021,12 +5027,16 @@ pdumper_set_marked_impl (const void *obj)
   eassert (offset < dump_private.header.cold_start);
   eassert (offset < dump_private.header.discardable_start);
   ptrdiff_t bitno = offset / DUMP_ALIGNMENT;
+  eassert (dump_bitset_bit_set_p (&dump_private.last_mark_bits, bitno));
   dump_bitset_set_bit (&dump_private.mark_bits, bitno);
 }
 
 void
 pdumper_clear_marks_impl (void)
 {
+  memcpy (dump_private.last_mark_bits.bits, dump_private.mark_bits.bits,
+	  sizeof (dump_private.last_mark_bits.bits[0])
+	  * dump_private.mark_bits.number_words);
   dump_bitset_clear (&dump_private.mark_bits);
 }
 
@@ -5244,6 +5254,7 @@ pdumper_load (const char *dump_filename)
   dump_off adj_discardable_start;
 
   struct dump_bitset mark_bits;
+  struct dump_bitset last_mark_bits;
   size_t mark_bits_needed;
 
   struct dump_header header_buf = { 0 };
@@ -5360,12 +5371,19 @@ pdumper_load (const char *dump_filename)
   if (!dump_bitset_init (&mark_bits, mark_bits_needed))
     goto out;
 
+  if (!dump_bitset_init (&last_mark_bits, mark_bits_needed))
+    goto out;
+
+  memset (last_mark_bits.bits, 0xff, sizeof (last_mark_bits.bits[0])
+	  * last_mark_bits.number_words);
+
   /* Point of no return.  */
   err = PDUMPER_LOAD_SUCCESS;
   dump_base = (uintptr_t) sections[DS_HOT].mapping;
   gflags.dumped_with_pdumper_ = true;
   dump_private.header = *header;
   dump_private.mark_bits = mark_bits;
+  dump_private.last_mark_bits = last_mark_bits;
   dump_public.start = dump_base;
   dump_public.end = dump_public.start + dump_size;
 
-- 
2.28.0