unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Paul Eggert <eggert@cs.ucla.edu>
To: Pip Cet <pipcet@gmail.com>, Eli Zaretskii <eliz@gnu.org>
Cc: 41321@debbugs.gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>
Subject: bug#41321: 27.0.91; Emacs aborts due to invalid pseudovector objects
Date: Mon, 25 May 2020 23:46:02 -0700	[thread overview]
Message-ID: <c9af54a4-0eb9-e1c6-7731-cdade3b2de04@cs.ucla.edu> (raw)
In-Reply-To: <4bab5f55-95fe-cf34-e490-1d4319728395@cs.ucla.edu>

[-- Attachment #1: Type: text/plain, Size: 629 bytes --]

On 5/25/20 8:33 PM, Paul Eggert wrote:
> On 5/25/20 4:28 AM, Pip Cet wrote:
> 
>> And I just noticed strings aren't aligned to LISP_ALIGNMENT on
>> x86_64-pc-linux-gnu.
> 
> Could you explain?

Oh, never mind, I figured it out. Sorry about the noise.

I installed the first attached patch to fix the bug on master (as a series of
commits, the leading ones not quite right unfortunately). This patch does what
you proposed, and also tightens up some of the related alignment checks.

I propose the second patch for emacs-27; it's limited to what you proposed,
namely, it weakens maybe_lisp_pointer to check only for GC_ALIGNMENT.

[-- Attachment #2: emacs.diff --]
[-- Type: text/x-patch, Size: 6907 bytes --]

diff --git a/src/alloc.c b/src/alloc.c
index d5a6d9167e..f8609398a3 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -104,6 +104,46 @@ Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2020 Free Software
 #include "w32heap.h"	/* for sbrk */
 #endif
 
+/* A type with alignment at least as large as any object that Emacs
+   allocates.  This is not max_align_t because some platforms (e.g.,
+   mingw) have buggy malloc implementations that do not align for
+   max_align_t.  This union contains types of all GCALIGNED_STRUCT
+   components visible here.  */
+union emacs_align_type
+{
+  struct frame frame;
+  struct Lisp_Bignum Lisp_Bignum;
+  struct Lisp_Bool_Vector Lisp_Bool_Vector;
+  struct Lisp_Char_Table Lisp_Char_Table;
+  struct Lisp_CondVar Lisp_CondVar;
+  struct Lisp_Finalizer Lisp_Finalizer;
+  struct Lisp_Float Lisp_Float;
+  struct Lisp_Hash_Table Lisp_Hash_Table;
+  struct Lisp_Marker Lisp_Marker;
+  struct Lisp_Misc_Ptr Lisp_Misc_Ptr;
+  struct Lisp_Mutex Lisp_Mutex;
+  struct Lisp_Overlay Lisp_Overlay;
+  struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table;
+  struct Lisp_Subr Lisp_Subr;
+  struct Lisp_User_Ptr Lisp_User_Ptr;
+  struct Lisp_Vector Lisp_Vector;
+  struct terminal terminal;
+  struct thread_state thread_state;
+  struct window window;
+
+  /* Omit the following since they would require including process.h
+     etc.  In practice their alignments never exceed that of the
+     structs already listed.  */
+#if 0
+  struct Lisp_Module_Function Lisp_Module_Function;
+  struct Lisp_Process Lisp_Process;
+  struct save_window_data save_window_data;
+  struct scroll_bar scroll_bar;
+  struct xwidget_view xwidget_view;
+  struct xwidget xwidget;
+#endif
+};
+
 /* MALLOC_SIZE_NEAR (N) is a good number to pass to malloc when
    allocating a block of memory with size close to N bytes.
    For best results N should be a power of 2.
@@ -112,9 +152,9 @@ Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2020 Free Software
    adds sizeof (size_t) to SIZE for internal overhead, and then rounds
    up to a multiple of MALLOC_ALIGNMENT.  Emacs can improve
    performance a bit on GNU platforms by arranging for the resulting
-   size to be a power of two.  This heuristic is good for glibc 2.0
-   (1997) through at least glibc 2.31 (2020), and does not affect
-   correctness on other platforms.  */
+   size to be a power of two.  This heuristic is good for glibc 2.26
+   (2017) and later, and does not affect correctness on other
+   platforms.  */
 
 #define MALLOC_SIZE_NEAR(n) \
   (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t))
@@ -655,25 +695,19 @@ buffer_memory_full (ptrdiff_t nbytes)
 #define COMMON_MULTIPLE(a, b) \
   ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
 
-/* LISP_ALIGNMENT is the alignment of Lisp objects.  It must be at
-   least GCALIGNMENT so that pointers can be tagged.  It also must be
-   at least as strict as the alignment of all the C types used to
-   implement Lisp objects; since pseudovectors can contain any C type,
-   this is max_align_t.  On recent GNU/Linux x86 and x86-64 this can
-   often waste up to 8 bytes, since alignof (max_align_t) is 16 but
-   typical vectors need only an alignment of 8.  Although shrinking
-   the alignment to 8 would save memory, it cost a 20% hit to Emacs
-   CPU performance on Fedora 28 x86-64 when compiled with gcc -m32.  */
-enum { LISP_ALIGNMENT = alignof (union { max_align_t x;
+/* Alignment needed for memory blocks that are allocated via malloc
+   and that contain Lisp objects.  On typical hosts malloc already
+   aligns sufficiently, but extra work is needed on oddball hosts
+   where Emacs would crash if malloc returned a non-GCALIGNED pointer.  */
+enum { LISP_ALIGNMENT = alignof (union { union emacs_align_type x;
 					 GCALIGNED_UNION_MEMBER }) };
 verify (LISP_ALIGNMENT % GCALIGNMENT == 0);
 
 /* True if malloc (N) is known to return storage suitably aligned for
    Lisp objects whenever N is a multiple of LISP_ALIGNMENT.  In
    practice this is true whenever alignof (max_align_t) is also a
-   multiple of LISP_ALIGNMENT.  This works even for x86, where some
-   platform combinations (e.g., GCC 7 and later, glibc 2.25 and
-   earlier) have bugs where alignof (max_align_t) is 16 even though
+   multiple of LISP_ALIGNMENT.  This works even for buggy platforms
+   like MinGW circa 2020, where alignof (max_align_t) is 16 even though
    the malloc alignment is only 8, and where Emacs still works because
    it never does anything that requires an alignment of 16.  */
 enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 };
@@ -4657,12 +4691,12 @@ mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts)
    collected, and false otherwise (i.e., false if it is easy to see
    that P cannot point to Lisp data that can be garbage collected).
    Symbols are implemented via offsets not pointers, but the offsets
-   are also multiples of LISP_ALIGNMENT.  */
+   are also multiples of GCALIGNMENT.  */
 
 static bool
 maybe_lisp_pointer (void *p)
 {
-  return (uintptr_t) p % LISP_ALIGNMENT == 0;
+  return (uintptr_t) p % GCALIGNMENT == 0;
 }
 
 /* If P points to Lisp data, mark that as live if it isn't already
@@ -4885,9 +4919,10 @@ test_setjmp (void)
    as a stack scan limit.  */
 typedef union
 {
-  /* Align the stack top properly.  Even if !HAVE___BUILTIN_UNWIND_INIT,
-     jmp_buf may not be aligned enough on darwin-ppc64.  */
-  max_align_t o;
+  /* Make sure stack_top and m_stack_bottom are properly aligned as GC
+     expects.  */
+  Lisp_Object o;
+  void *p;
 #ifndef HAVE___BUILTIN_UNWIND_INIT
   sys_jmp_buf j;
   char c;
diff --git a/src/lisp.h b/src/lisp.h
index 85bdc172b2..8bd83a888c 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -277,7 +277,8 @@ DEFINE_GDB_SYMBOL_END (VALMASK)
    allocation in a containing union that has GCALIGNED_UNION_MEMBER)
    and does not contain a GC-aligned struct or union, putting
    GCALIGNED_STRUCT after its closing '}' can help the compiler
-   generate better code.
+   generate better code.  Also, such structs should be added to the
+   emacs_align_type union in alloc.c.
 
    Although these macros are reasonably portable, they are not
    guaranteed on non-GCC platforms, as C11 does not require support
diff --git a/src/thread.c b/src/thread.c
index df1a705382..b638dd77f8 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -717,12 +717,17 @@ run_thread (void *state)
 {
   /* Make sure stack_top and m_stack_bottom are properly aligned as GC
      expects.  */
-  max_align_t stack_pos;
+  union
+  {
+    Lisp_Object o;
+    void *p;
+    char c;
+  } stack_pos;
 
   struct thread_state *self = state;
   struct thread_state **iter;
 
-  self->m_stack_bottom = self->stack_top = (char *) &stack_pos;
+  self->m_stack_bottom = self->stack_top = &stack_pos.c;
   self->thread_id = sys_thread_self ();
 
   if (self->thread_name)

[-- Attachment #3: 0001-Fix-aborts-due-to-GC-losing-pseudovectors.patch --]
[-- Type: text/x-patch, Size: 1191 bytes --]

From 7466aeeb4ac3dace283ecef00c2b38148b56b3b3 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon, 25 May 2020 23:39:37 -0700
Subject: [PATCH] Fix aborts due to GC losing pseudovectors

Problem reported by Eli Zaretskii (Bug#41321).
* src/alloc.c (maybe_lisp_pointer): Modulo GCALIGNMENT,
not modulo LISP_ALIGNMENT.  Master has a more-elaborate fix.
Do not merge to master.
---
 src/alloc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index 1c6b664b22..c7a4a3ee86 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4589,12 +4589,12 @@ mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts)
    collected, and false otherwise (i.e., false if it is easy to see
    that P cannot point to Lisp data that can be garbage collected).
    Symbols are implemented via offsets not pointers, but the offsets
-   are also multiples of LISP_ALIGNMENT.  */
+   are also multiples of GCALIGNMENT.  */
 
 static bool
 maybe_lisp_pointer (void *p)
 {
-  return (uintptr_t) p % LISP_ALIGNMENT == 0;
+  return (uintptr_t) p % GCALIGNMENT == 0;
 }
 
 /* If P points to Lisp data, mark that as live if it isn't already
-- 
2.17.1


  parent reply	other threads:[~2020-05-26  6:46 UTC|newest]

Thread overview: 132+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-16 10:33 bug#41321: 27.0.91; Emacs aborts due to invalid pseudovector objects Eli Zaretskii
2020-05-16 16:33 ` Paul Eggert
2020-05-16 16:47   ` Eli Zaretskii
2020-05-17 10:56 ` Pip Cet
2020-05-17 15:28   ` Eli Zaretskii
2020-05-17 15:57     ` Eli Zaretskii
2020-05-22  7:22       ` Eli Zaretskii
2020-05-22  8:35         ` Andrea Corallo
2020-05-22 11:04           ` Eli Zaretskii
2020-05-22 12:55             ` Andrea Corallo
2020-05-22 10:54         ` Eli Zaretskii
2020-05-22 11:47         ` Pip Cet
2020-05-22 12:13           ` Eli Zaretskii
2020-05-22 12:39             ` Pip Cet
2020-05-22 12:48               ` Eli Zaretskii
2020-05-22 14:04                 ` Pip Cet
2020-05-22 14:26                   ` Eli Zaretskii
2020-05-22 14:40                     ` Andrea Corallo
2020-05-22 19:03                       ` Eli Zaretskii
     [not found]                         ` <CAOqdjBdpU4U1NqErNH0idBmUxNeE3fL=2=KKpo9kbCM3DhW5gA@mail.gmail.com>
2020-05-23 17:58                           ` Andrea Corallo
2020-05-23 22:37                             ` Stefan Monnier
2020-05-23 22:41                               ` Pip Cet
2020-05-23 23:26                                 ` Stefan Monnier
2020-05-22 12:32           ` Eli Zaretskii
2020-05-29  9:51           ` Eli Zaretskii
2020-05-29 10:00             ` Pip Cet
2020-05-23 23:54         ` Pip Cet
2020-05-24 14:24           ` Eli Zaretskii
2020-05-24 15:00             ` Pip Cet
2020-05-24 16:25               ` Eli Zaretskii
2020-05-24 16:55                 ` Eli Zaretskii
2020-05-24 18:03                   ` Pip Cet
2020-05-24 18:40                     ` Eli Zaretskii
2020-05-24 19:40                       ` Pip Cet
2020-05-25  2:30                         ` Eli Zaretskii
2020-05-25  6:40                           ` Pip Cet
2020-05-25 11:28                             ` Pip Cet
2020-05-25 14:53                               ` Eli Zaretskii
2020-05-25 15:12                                 ` Stefan Monnier
2020-05-26  3:39                                 ` Paul Eggert
2020-05-26  3:33                               ` Paul Eggert
2020-05-26  6:18                                 ` Pip Cet
2020-05-26  7:51                                   ` Paul Eggert
2020-05-26  8:27                                     ` Pip Cet
2020-05-26  6:46                                 ` Paul Eggert [this message]
2020-05-26 15:17                                   ` Eli Zaretskii
2020-05-26 22:49                                     ` Paul Eggert
2020-05-27 15:26                                       ` Eli Zaretskii
2020-05-27 16:58                                         ` Paul Eggert
2020-05-27 17:33                                           ` Eli Zaretskii
2020-05-27 17:53                                             ` Paul Eggert
2020-05-27 18:24                                               ` Eli Zaretskii
2020-05-27 18:39                                                 ` Paul Eggert
2020-05-28  2:43                                               ` Stefan Monnier
2020-05-28  7:27                                                 ` Eli Zaretskii
2020-05-28  7:41                                                   ` Paul Eggert
2020-05-28 13:30                                                     ` Stefan Monnier
2020-05-28 14:28                                                       ` Pip Cet
2020-05-28 16:24                                                         ` Stefan Monnier
2020-05-29  9:43                                                         ` Pip Cet
2020-05-29 18:31                                                           ` Paul Eggert
2020-05-29 18:37                                                             ` Pip Cet
2020-05-29 19:32                                                               ` Paul Eggert
2020-05-29 19:37                                                                 ` Pip Cet
2020-05-29 20:26                                                                 ` Stefan Monnier
2020-05-29 20:40                                                                   ` Paul Eggert
2020-05-30  5:54                                                                     ` Eli Zaretskii
2020-05-30 17:52                                                                       ` Paul Eggert
2020-05-30 18:11                                                                         ` Eli Zaretskii
2020-05-30 18:17                                                                           ` Paul Eggert
2020-05-30  5:51                                                                   ` Eli Zaretskii
2020-05-30 14:26                                                                     ` Stefan Monnier
2020-05-27 17:57                                           ` Pip Cet
2020-05-27 18:39                                             ` Paul Eggert
2020-05-27 18:56                                               ` Pip Cet
2020-05-28  1:21                                                 ` Paul Eggert
2020-05-28  6:31                                                   ` Pip Cet
2020-05-28  7:47                                                     ` Paul Eggert
2020-05-28  8:11                                                       ` Pip Cet
2020-05-28 18:27                                           ` Eli Zaretskii
2020-05-28 19:33                                             ` Paul Eggert
2020-05-29  6:19                                               ` Eli Zaretskii
2020-05-29 20:24                                                 ` Paul Eggert
2020-05-29 21:01                                                   ` Pip Cet
2020-05-30  5:58                                                     ` Eli Zaretskii
2020-05-30  7:19                                                       ` Pip Cet
2020-05-30  9:08                                                         ` Eli Zaretskii
2020-05-30 11:06                                                           ` Pip Cet
2020-05-30 11:31                                                             ` Eli Zaretskii
2020-05-30 13:29                                                               ` Pip Cet
2020-05-30 16:32                                                                 ` Eli Zaretskii
2020-05-30 16:36                                                                   ` Pip Cet
2020-05-30 16:45                                                                     ` Eli Zaretskii
2020-05-30 18:04                                                                 ` Paul Eggert
2020-05-30 18:12                                                                   ` Pip Cet
2020-05-30 18:16                                                                   ` Eli Zaretskii
2020-05-30 18:45                                                                     ` Paul Eggert
2020-05-30 18:39                                                                   ` Pip Cet
2020-05-30 18:57                                                                     ` Paul Eggert
2020-05-30 19:06                                                                       ` Pip Cet
2020-05-30 21:27                                                                         ` Paul Eggert
2020-05-30 21:49                                                                           ` Pip Cet
2020-05-30 22:23                                                                             ` Paul Eggert
2020-05-30 22:54                                                                               ` Pip Cet
2020-05-30 16:31                                                     ` Paul Eggert
2020-05-30 16:42                                                       ` Eli Zaretskii
2020-05-30 17:06                                                         ` Paul Eggert
2020-05-30 17:22                                                           ` Eli Zaretskii
2020-05-30 18:12                                                             ` Paul Eggert
2020-05-30 18:21                                                               ` Eli Zaretskii
2020-05-30 19:14                                                                 ` Paul Eggert
2020-05-30 19:33                                                                   ` Eli Zaretskii
2020-05-30 22:18                                                                     ` Paul Eggert
2020-05-31 15:48                                                                       ` Eli Zaretskii
2020-06-01 14:48                                                                         ` Eli Zaretskii
2020-09-27 14:39                                                                           ` Lars Ingebrigtsen
2020-09-27 14:45                                                                             ` Pip Cet
2020-09-27 15:02                                                                               ` Lars Ingebrigtsen
2020-09-27 15:16                                                                             ` Eli Zaretskii
2020-05-30 16:53                                                       ` Pip Cet
2020-05-30  5:50                                                   ` Eli Zaretskii
2020-05-29  8:25                                               ` Pip Cet
2020-05-25 15:14                             ` Eli Zaretskii
2020-05-25 17:41                               ` Pip Cet
2020-05-24 19:00               ` Andy Moreton
2020-05-24 19:09                 ` Pip Cet
2020-05-29 10:16         ` Eli Zaretskii
2020-05-29 10:34           ` Pip Cet
2020-05-29 10:55             ` Eli Zaretskii
2020-05-29 11:47               ` Pip Cet
2020-05-29 13:52                 ` Eli Zaretskii
2020-05-29 14:19                   ` Pip Cet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c9af54a4-0eb9-e1c6-7731-cdade3b2de04@cs.ucla.edu \
    --to=eggert@cs.ucla.edu \
    --cc=41321@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=pipcet@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).