emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs-25 b88e9cd: malloc.h hygiene


From: Paul Eggert
Subject: [Emacs-diffs] emacs-25 b88e9cd: malloc.h hygiene
Date: Wed, 27 Jan 2016 07:01:54 +0000

branch: emacs-25
commit b88e9cded7ae3756e3a2ec4a23e8df352a0239f9
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    malloc.h hygiene
    
    This attempts to future-proof Emacs a bit against possible glibc
    changes, by having Emacs use <malloc.h> declarations rather than
    coding them up by hand.  Problem noted by Florian Weimer in:
    https://sourceware.org/ml/libc-alpha/2016-01/msg00777.html
    Implement this mainly by moving malloc.h-related functions from
    emacs.c (which does not include <malloc.h>) to alloc.c (which does).
    * src/alloc.c (my_heap_start) [DOUG_LEA_MALLOC || GNU_LINUX]:
    New function.
    The remaining changes to this file apply only if DOUG_LEA_MALLOC.
    (alloc_unexec_pre, alloc_unexec_post): New functions.
    (malloc_initialize_hook): Use my_heap_start and alloc_unexec_post.
    (__MALLOC_HOOK_VOLATILE): New macro, if not already defined.
    (__malloc_initialize_hook): Use it.
    (malloc_state_ptr, malloc_initialize_hook, __malloc_initialize_hook):
    Move here from ...
    * src/emacs.c: ... here.
    (malloc_get_state, malloc_set_state): Remove extern decls.
    (my_heap_start) [DOUG_LEA_MALLOC || GNU_LINUX]: Remove static var.
    All uses changed to similarly-named new function.
    (Fdump_emacs): Use new functions alloc_unexec_pre, alloc_unexec_post.
    * src/lisp.h (my_heap_start, alloc_unexec_pre, alloc_unexec_post):
    New decls.
---
 src/alloc.c |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/emacs.c |   78 ++++-------------------------------------------------------
 src/lisp.h  |    8 ++++++
 3 files changed, 88 insertions(+), 74 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index 03dacc7..d379761 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -92,6 +92,18 @@ static bool valgrind_p;
 #include "w32heap.h"   /* for sbrk */
 #endif
 
+#if defined DOUG_LEA_MALLOC || defined GNU_LINUX
+/* The address where the heap starts.  */
+void *
+my_heap_start (void)
+{
+  static void *start;
+  if (! start)
+    start = sbrk (0);
+  return start;
+}
+#endif
+
 #ifdef DOUG_LEA_MALLOC
 
 #include <malloc.h>
@@ -101,7 +113,69 @@ static bool valgrind_p;
 
 #define MMAP_MAX_AREAS 100000000
 
-#endif /* not DOUG_LEA_MALLOC */
+/* A pointer to the memory allocated that copies that static data
+   inside glibc's malloc.  */
+static void *malloc_state_ptr;
+
+/* Get and free this pointer; useful around unexec.  */
+void
+alloc_unexec_pre (void)
+{
+  malloc_state_ptr = malloc_get_state ();
+}
+void
+alloc_unexec_post (void)
+{
+  free (malloc_state_ptr);
+}
+
+/* Restore the dumped malloc state.  Because malloc can be invoked
+   even before main (e.g. by the dynamic linker), the dumped malloc
+   state must be restored as early as possible using this special hook.  */
+static void
+malloc_initialize_hook (void)
+{
+  static bool malloc_using_checking;
+
+  if (! initialized)
+    {
+      my_heap_start ();
+      malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
+    }
+  else
+    {
+      if (!malloc_using_checking)
+       {
+         /* Work around a bug in glibc's malloc.  MALLOC_CHECK_ must be
+            ignored if the heap to be restored was constructed without
+            malloc checking.  Can't use unsetenv, since that calls malloc.  */
+         char **p = environ;
+         if (p)
+           for (; *p; p++)
+             if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
+               {
+                 do
+                   *p = p[1];
+                 while (*++p);
+
+                 break;
+               }
+       }
+
+      malloc_set_state (malloc_state_ptr);
+# ifndef XMALLOC_OVERRUN_CHECK
+      alloc_unexec_post ();
+# endif
+    }
+}
+
+# ifndef __MALLOC_HOOK_VOLATILE
+#  define __MALLOC_HOOK_VOLATILE
+# endif
+voidfuncptr __MALLOC_HOOK_VOLATILE __malloc_initialize_hook
+  = malloc_initialize_hook;
+
+#endif
 
 /* Mark, unmark, query mark bit of a Lisp string.  S must be a pointer
    to a struct Lisp_String.  */
diff --git a/src/emacs.c b/src/emacs.c
index 89d8ca7..e3cfad0 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -133,20 +133,7 @@ bool might_dump;
 extern void unexec_init_emacs_zone (void);
 #endif
 
-#ifdef DOUG_LEA_MALLOC
-/* Preserves a pointer to the memory allocated that copies that
-   static data inside glibc's malloc.  */
-static void *malloc_state_ptr;
-/* From glibc, a routine that returns a copy of the malloc internal state.  */
-extern void *malloc_get_state (void);
-/* From glibc, a routine that overwrites the malloc internal state.  */
-extern int malloc_set_state (void *);
-/* True if the MALLOC_CHECK_ environment variable was set while
-   dumping.  Used to work around a bug in glibc's malloc.  */
-static bool malloc_using_checking;
-#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
 extern void malloc_enable_thread (void);
-#endif
 
 /* If true, Emacs should not attempt to use a window-specific code,
    but instead should use the virtual terminal under which it was started.  */
@@ -165,11 +152,6 @@ bool display_arg;
    Tells GC how to save a copy of the stack.  */
 char *stack_bottom;
 
-#if defined (DOUG_LEA_MALLOC) || defined (GNU_LINUX)
-/* The address where the heap starts (from the first sbrk (0) call).  */
-static void *my_heap_start;
-#endif
-
 #ifdef GNU_LINUX
 /* The gap between BSS end and heap start as far as we can tell.  */
 static uprintmax_t heap_bss_diff;
@@ -651,51 +633,6 @@ argmatch (char **argv, int argc, const char *sstr, const 
char *lstr,
     }
 }
 
-#ifdef DOUG_LEA_MALLOC
-
-/* malloc can be invoked even before main (e.g. by the dynamic
-   linker), so the dumped malloc state must be restored as early as
-   possible using this special hook.  */
-
-static void
-malloc_initialize_hook (void)
-{
-  if (initialized)
-    {
-      if (!malloc_using_checking)
-       /* Work around a bug in glibc's malloc.  MALLOC_CHECK_ must be
-          ignored if the heap to be restored was constructed without
-          malloc checking.  Can't use unsetenv, since that calls malloc.  */
-       {
-         char **p;
-
-         for (p = environ; p && *p; p++)
-           if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
-             {
-               do
-                 *p = p[1];
-               while (*++p);
-               break;
-             }
-       }
-
-      malloc_set_state (malloc_state_ptr);
-#ifndef XMALLOC_OVERRUN_CHECK
-      free (malloc_state_ptr);
-#endif
-    }
-  else
-    {
-      if (my_heap_start == 0)
-        my_heap_start = sbrk (0);
-      malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
-    }
-}
-
-void (*__malloc_initialize_hook) (void) EXTERNALLY_VISIBLE = 
malloc_initialize_hook;
-
-#endif /* DOUG_LEA_MALLOC */
-
 /* Close standard output and standard error, reporting any write
    errors as best we can.  This is intended for use with atexit.  */
 static void
@@ -743,10 +680,8 @@ main (int argc, char **argv)
 #ifdef GNU_LINUX
   if (!initialized)
     {
-      if (my_heap_start == 0)
-        my_heap_start = sbrk (0);
-
-      heap_bss_diff = (char *)my_heap_start - max (my_endbss, 
my_endbss_static);
+      char *heap_start = my_heap_start ();
+      heap_bss_diff = heap_start - max (my_endbss, my_endbss_static);
     }
 #endif
 
@@ -2145,15 +2080,12 @@ You must run Emacs in batch mode in order to dump it.  
*/)
   memory_warnings (my_edata, malloc_warning);
 #endif /* not WINDOWSNT */
 #endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
-#ifdef DOUG_LEA_MALLOC
-  malloc_state_ptr = malloc_get_state ();
-#endif
+
+  alloc_unexec_pre ();
 
   unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0);
 
-#ifdef DOUG_LEA_MALLOC
-  free (malloc_state_ptr);
-#endif
+  alloc_unexec_post ();
 
 #ifdef WINDOWSNT
   Vlibrary_cache = Qnil;
diff --git a/src/lisp.h b/src/lisp.h
index 6be2104..82cbca8 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3590,6 +3590,7 @@ extern void parse_str_as_multibyte (const unsigned char 
*, ptrdiff_t,
                                    ptrdiff_t *, ptrdiff_t *);
 
 /* Defined in alloc.c.  */
+extern void *my_heap_start (void);
 extern void check_pure_size (void);
 extern void free_misc (Lisp_Object);
 extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
@@ -3601,6 +3602,13 @@ extern void mark_object (Lisp_Object);
 #if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
 extern void refill_memory_reserve (void);
 #endif
+#ifdef DOUG_LEA_MALLOC
+extern void alloc_unexec_pre (void);
+extern void alloc_unexec_post (void);
+#else
+INLINE void alloc_unexec_pre (void) {}
+INLINE void alloc_unexec_post (void) {}
+#endif
 extern const char *pending_malloc_warning;
 extern Lisp_Object zero_vector;
 extern Lisp_Object *stack_base;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]