aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2016-01-26 23:00:10 -0800
committerPaul Eggert2016-01-26 23:01:48 -0800
commitb88e9cded7ae3756e3a2ec4a23e8df352a0239f9 (patch)
tree201806e4c770722fa29ef77365030df930751d06 /src/alloc.c
parentcf17002326ba29d78f20118e0016dbd32fc3527e (diff)
downloademacs-b88e9cded7ae3756e3a2ec4a23e8df352a0239f9.tar.gz
emacs-b88e9cded7ae3756e3a2ec4a23e8df352a0239f9.zip
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.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 03dacc77c6e..d379761c168 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -92,6 +92,18 @@ static bool valgrind_p;
92#include "w32heap.h" /* for sbrk */ 92#include "w32heap.h" /* for sbrk */
93#endif 93#endif
94 94
95#if defined DOUG_LEA_MALLOC || defined GNU_LINUX
96/* The address where the heap starts. */
97void *
98my_heap_start (void)
99{
100 static void *start;
101 if (! start)
102 start = sbrk (0);
103 return start;
104}
105#endif
106
95#ifdef DOUG_LEA_MALLOC 107#ifdef DOUG_LEA_MALLOC
96 108
97#include <malloc.h> 109#include <malloc.h>
@@ -101,7 +113,69 @@ static bool valgrind_p;
101 113
102#define MMAP_MAX_AREAS 100000000 114#define MMAP_MAX_AREAS 100000000
103 115
104#endif /* not DOUG_LEA_MALLOC */ 116/* A pointer to the memory allocated that copies that static data
117 inside glibc's malloc. */
118static void *malloc_state_ptr;
119
120/* Get and free this pointer; useful around unexec. */
121void
122alloc_unexec_pre (void)
123{
124 malloc_state_ptr = malloc_get_state ();
125}
126void
127alloc_unexec_post (void)
128{
129 free (malloc_state_ptr);
130}
131
132/* Restore the dumped malloc state. Because malloc can be invoked
133 even before main (e.g. by the dynamic linker), the dumped malloc
134 state must be restored as early as possible using this special hook. */
135static void
136malloc_initialize_hook (void)
137{
138 static bool malloc_using_checking;
139
140 if (! initialized)
141 {
142 my_heap_start ();
143 malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
144 }
145 else
146 {
147 if (!malloc_using_checking)
148 {
149 /* Work around a bug in glibc's malloc. MALLOC_CHECK_ must be
150 ignored if the heap to be restored was constructed without
151 malloc checking. Can't use unsetenv, since that calls malloc. */
152 char **p = environ;
153 if (p)
154 for (; *p; p++)
155 if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
156 {
157 do
158 *p = p[1];
159 while (*++p);
160
161 break;
162 }
163 }
164
165 malloc_set_state (malloc_state_ptr);
166# ifndef XMALLOC_OVERRUN_CHECK
167 alloc_unexec_post ();
168# endif
169 }
170}
171
172# ifndef __MALLOC_HOOK_VOLATILE
173# define __MALLOC_HOOK_VOLATILE
174# endif
175voidfuncptr __MALLOC_HOOK_VOLATILE __malloc_initialize_hook
176 = malloc_initialize_hook;
177
178#endif
105 179
106/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer 180/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
107 to a struct Lisp_String. */ 181 to a struct Lisp_String. */