Subject: Re: bug#31996: 27.0.50; [w32] while dumping: assertion failed: specpdl_ptr->kind == SPECPDL_UNWIND_PTR && specpdl_ptr->unwind_ptr.func == xfree

From: Paul Eggert <[email-masked]>
Date: Thu, 28 Jun 2018 13:55:50 -0700

Thanks for reporting that. I didn't observe the problem on Fedora 28. Anyway, I 
installed the attached patch, which should fix it.
>From ddc4371a89e5500e0203bed4b0ad453925b1c74f Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Thu, 28 Jun 2018 13:49:48 -0700
Subject: [PATCH] Fix recently-introduced SAFE_FREE bug

Problem reported by Andy Moreton (Bug#31996).
* src/lisp.h (union specbinding.unwind_array):
Remove unused member func.  Move array after nelts, as this is
likely to generate more efficient code in safe_free, which can
call xfree with the same value either way.
(safe_free): Also handle SPECPDL_UNWIND_AWAY.
---
 src/lisp.h | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/lisp.h b/src/lisp.h
index b544d81..cf7b8c0 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3058,9 +3058,8 @@ union specbinding
     } unwind;
     struct {
       ENUM_BF (specbind_tag) kind : CHAR_BIT;
-      void (*func) (Lisp_Object);
-      Lisp_Object *array;
       ptrdiff_t nelts;
+      Lisp_Object *array;
     } unwind_array;
     struct {
       ENUM_BF (specbind_tag) kind : CHAR_BIT;
@@ -4543,9 +4542,16 @@ safe_free (ptrdiff_t sa_count)
   while (specpdl_ptr != specpdl + sa_count)
     {
       specpdl_ptr--;
-      eassert (specpdl_ptr->kind == SPECPDL_UNWIND_PTR
-	       && specpdl_ptr->unwind_ptr.func == xfree);
-      xfree (specpdl_ptr->unwind_ptr.arg);
+      if (specpdl_ptr->kind == SPECPDL_UNWIND_PTR)
+	{
+	  eassert (specpdl_ptr->unwind_ptr.func == xfree);
+	  xfree (specpdl_ptr->unwind_ptr.arg);
+	}
+      else
+	{
+	  eassert (specpdl_ptr->kind == SPECPDL_UNWIND_ARRAY);
+	  xfree (specpdl_ptr->unwind_array.array);
+	}
     }
 }
 
-- 
2.7.4