Subject: bug#27416: closed (Re: [PROPOSED] Simplify malloc replacement on glibc)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 21 Jun 2017 21:35:02 +0000

Your bug report

#27416: [PROPOSED] Simplify malloc replacement on glibc

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
27416: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=27416
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: [PROPOSED] Simplify malloc replacement on glibc
From: Paul Eggert <[email-masked]>
To: [email-masked]
Date: Wed, 21 Jun 2017 14:34:46 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

After looking into this some more, I decided not to pursue this. The 
patch has a typo, and when I fixed the typo and debugged Emacs I found 
that the patch sometimes made Emacs crashed. Apparently the problem is 
that the dynamic linker uses gmalloc once the patch is made, and gmalloc 
is not compatible with what the dynamic linker expects. Oh well. Closing.

Subject: [PROPOSED] Simplify malloc replacement on glibc
From: Paul Eggert <[email-masked]>
To: [email-masked]
Cc: Paul Eggert <[email-masked]>
Date: Sat, 17 Jun 2017 17:28:18 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

This avoids the need to build lib/e-gettime.o etc. on glibc
platforms, as plain lib/gettime.o will do.
* configure.ac (HAVE___LIBC_MALLOC): New symbol.
* lib/Makefile.in (all): Don’t build libegnu.a if HAVE___LIBC_MALLOC.
* lib/gnulib.mk.in: Regenerate.
* src/Makefile.in (HAVE___LIBC_MALLOC): New macro.
(LIBEGNU_ARCHIVE): Use it, so that libegnu.a is not needed
if HAVE___LIBC_MALLOC.
* src/conf_post.h (malloc, realloc, aligned_alloc, calloc, free):
Do not define as macros if HAVE___LIBC_MALLOC, since they are
now defined as functions in that case.
* src/gmalloc.c (hybrid_malloc, hybrid_realloc, hybrid_calloc)
(hybrid_aligned_alloc, hybrid_free): Define to plain malloc etc.,
if HAVE___LIBC_MALLOC, since the hybrid functions replace the
standard ones in that case.
(malloc, realloc, calloc, free): Define to __libc_malloc etc.,
if HAVE___LIBC_MALLOC, as that is the way to call the standard ones
in that case.
(aligned_alloc): No need to declare if HAVE___LIBC_MALLOC,
since we don’t replace it.
(hybrid_aligned_alloc): Do not call aligned_alloc if
HAVE___LIBC_MALLOC, since there is no __libc_aligned_alloc.
Use posix_memalign instead.
---
 configure.ac     |  3 +++
 lib/Makefile.in  |  2 +-
 lib/gnulib.mk.in |  1 +
 src/Makefile.in  |  4 +++-
 src/conf_post.h  |  9 ++++-----
 src/gmalloc.c    | 16 ++++++++++++++--
 6 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index ef61107..7dafd49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2214,6 +2214,7 @@ AC_DEFUN
 
 GMALLOC_OBJ=
 HYBRID_MALLOC=
+HAVE___LIBC_MALLOC=
 if test "${system_malloc}" = "yes"; then
   AC_DEFINE([SYSTEM_MALLOC], 1,
     [Define to 1 to use the system memory allocator, even if it is not
@@ -2230,6 +2231,7 @@ AC_DEFUN
   GNU_MALLOC_reason=" (only before dumping)"
   GMALLOC_OBJ=gmalloc.o
   VMLIMIT_OBJ=
+  AC_CHECK_FUNCS([__libc_malloc], [HAVE___LIBC_MALLOC=1])
 else
   test "$doug_lea_malloc" != "yes" && GMALLOC_OBJ=gmalloc.o
   VMLIMIT_OBJ=vm-limit.o
@@ -2249,6 +2251,7 @@ AC_DEFUN
   fi
 fi
 AC_SUBST([HYBRID_MALLOC])
+AC_SUBST([HAVE___LIBC_MALLOC])
 AC_SUBST(GMALLOC_OBJ)
 AC_SUBST(VMLIMIT_OBJ)
 
diff --git a/lib/Makefile.in b/lib/Makefile.in
index ee41ea3..cd18da7 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -90,7 +90,7 @@ .c.o:
 e-%.o: %.c
 	$(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -Demacs -o $@ $<
 
-all: libgnu.a $(if $(HYBRID_MALLOC),libegnu.a)
+all: libgnu.a $(if $(HYBRID_MALLOC),$(if $(HAVE___LIBC_MALLOC),,libegnu.a))
 
 libgnu.a: $(libgnu_a_OBJECTS)
 	$(AM_V_at)rm -f $@
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 509089e..4afe4b3 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -522,6 +522,7 @@ HAVE_WCHAR_T = @HAVE_WCHAR_T@
 HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
 HAVE_XSERVER = @HAVE_XSERVER@
 HAVE__EXIT = @HAVE__EXIT@
+HAVE___LIBC_MALLOC = @HAVE___LIBC_MALLOC@
 HYBRID_MALLOC = @HYBRID_MALLOC@
 IMAGEMAGICK_CFLAGS = @IMAGEMAGICK_CFLAGS@
 IMAGEMAGICK_LIBS = @IMAGEMAGICK_LIBS@
diff --git a/src/Makefile.in b/src/Makefile.in
index 2be24ac..f1b1aeb 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -257,6 +257,7 @@ XDBE_CFLAGS =
 WIDGET_OBJ=@WIDGET_OBJ@
 
 HYBRID_MALLOC = @HYBRID_MALLOC@
+HAVE___LIBC_MALLOC = @HAVE___LIBC_MALLOC@
 
 ## cygw32.o if CYGWIN, otherwise empty.
 CYGWIN_OBJ=@CYGWIN_OBJ@
@@ -584,7 +585,8 @@ globals.h:
 
 $(ALLOBJS): globals.h
 
-LIBEGNU_ARCHIVE = $(lib)/lib$(if $(HYBRID_MALLOC),e)gnu.a
+LIBEGNU_ARCHIVE = \
+  $(lib)/lib$(if $(HYBRID_MALLOC),$(if $(HAVE___LIBC_MALLOC),,e))gnu.a
 
 $(LIBEGNU_ARCHIVE): $(config_h)
 	$(MAKE) -C $(lib) all
diff --git a/src/conf_post.h b/src/conf_post.h
index e1d6a93..af10397 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -105,17 +105,16 @@ typedef bool bool_bf;
 
 /* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use
    gmalloc before dumping and the system malloc after dumping.
-   hybrid_malloc and friends, defined in gmalloc.c, are wrappers that
-   accomplish this.  */
-#ifdef HYBRID_MALLOC
-#ifdef emacs
+   This is done via wrappers defined in gmalloc.c, whose names are
+   'malloc' etc. if HAVE___LIBC_MALLOC is defined, and 'hybrid_malloc'
+   etc. otherwise.  */
+#if defined HYBRID_MALLOC && !defined HAVE___LIBC_MALLOC && defined emacs
 #define malloc hybrid_malloc
 #define realloc hybrid_realloc
 #define aligned_alloc hybrid_aligned_alloc
 #define calloc hybrid_calloc
 #define free hybrid_free
 #endif
-#endif	/* HYBRID_MALLOC */
 
 /* We have to go this route, rather than the old hpux9 approach of
    renaming the functions via macros.  The system's stdlib.h has fully
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 49f1faf..9de0079 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -1709,13 +1709,25 @@ valloc (size_t size)
 #undef aligned_alloc
 #undef free
 
+#ifdef HAVE___LIBC_MALLOC
+# define hybrid_malloc malloc
+# define hybrid_realloc realloc
+# define hybrid_calloc calloc
+# define hybrid_aligned_alloc aligned_alloc
+# define hybrid_free free
+# define malloc __libc_malloc
+# define realloc __libc_realloc
+# define calloc __libc_calloc
+# define free __libc_free
+#endif
+
 #ifdef HYBRID_MALLOC
 /* Declare system malloc and friends.  */
 extern void *malloc (size_t size);
 extern void *realloc (void *ptr, size_t size);
 extern void *calloc (size_t nmemb, size_t size);
 extern void free (void *ptr);
-#ifdef HAVE_ALIGNED_ALLOC
+#if defined HAVE_ALIGNED_ALLOC && !defined HAVE___LIBC_MALLOC
 extern void *aligned_alloc (size_t alignment, size_t size);
 #elif defined HAVE_POSIX_MEMALIGN
 extern int posix_memalign (void **memptr, size_t alignment, size_t size);
@@ -1759,7 +1771,7 @@ hybrid_aligned_alloc (size_t alignment, size_t size)
   if (!DUMPED)
     return galigned_alloc (alignment, size);
   /* The following is copied from alloc.c */
-#ifdef HAVE_ALIGNED_ALLOC
+#if defined HAVE_ALIGNED_ALLOC && !defined HAVE___LIBC_MALLOC
   return aligned_alloc (alignment, size);
 #else  /* HAVE_POSIX_MEMALIGN */
   void *p;
-- 
2.9.4