aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2013-12-26 00:57:28 -0800
committerPaul Eggert2013-12-26 00:57:28 -0800
commite76119d7542b19eb03f8d725480cbf98f7fa03d9 (patch)
treebdc730dbcd0f54ca25623960feb8df4dfce073b7 /src/alloc.c
parent2200a8c91de23f9749d1b3c961c4f8bb3145ddfa (diff)
downloademacs-e76119d7542b19eb03f8d725480cbf98f7fa03d9.tar.gz
emacs-e76119d7542b19eb03f8d725480cbf98f7fa03d9.zip
Fix core dumps with gcc -fsanitize=address and GNU/Linux.
On my Fedora 19 platform the core dumps were so big that my desktop became nearly catatonic. * configure.ac: Check whether addresses are sanitized. (CANNOT_DUMP): Warn if addresses are sanitized and not CANNOT_DUMP. (DOUG_LEA_MALLOC): Do not define if addresses are sanitized. (SYSTEM_MALLOC): Define if addresses are sanitized. * src/alloc.c (no_sanitize_memcpy) [MAX_SAVE_STACK > 0]: New function. (Fgarbage_collect) [MAX_SAVE_STACK > 0]: Use it. (USE_ALIGNED_MALLOC): Do not define if addresses are sanitized. (mark_memory): Use ATTRIBUTE_NO_SANITIZE_ADDRESS rather than a clang-only syntax. * src/conf_post.h (__has_feature): New macro, if not already defined. (ADDRESS_SANITIZER, ADDRESS_SANITIZER_WORKAROUND) (ATTRIBUTE_NO_SANITIZE_ADDRESS): New macros.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 447b465a076..14c322a3a64 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -203,7 +203,27 @@ const char *pending_malloc_warning;
203#if MAX_SAVE_STACK > 0 203#if MAX_SAVE_STACK > 0
204static char *stack_copy; 204static char *stack_copy;
205static ptrdiff_t stack_copy_size; 205static ptrdiff_t stack_copy_size;
206#endif 206
207/* Copy to DEST a block of memory from SRC of size SIZE bytes,
208 avoiding any address sanitization. */
209
210static void * ATTRIBUTE_NO_SANITIZE_ADDRESS
211no_sanitize_memcpy (void *dest, void const *src, size_t size)
212{
213 if (! ADDRESS_SANITIZER)
214 return memcpy (dest, src, size);
215 else
216 {
217 size_t i;
218 char *d = dest;
219 char const *s = src;
220 for (i = 0; i < size; i++)
221 d[i] = s[i];
222 return dest;
223 }
224}
225
226#endif /* MAX_SAVE_STACK > 0 */
207 227
208static Lisp_Object Qconses; 228static Lisp_Object Qconses;
209static Lisp_Object Qsymbols; 229static Lisp_Object Qsymbols;
@@ -920,20 +940,26 @@ lisp_free (void *block)
920/* The entry point is lisp_align_malloc which returns blocks of at most 940/* The entry point is lisp_align_malloc which returns blocks of at most
921 BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ 941 BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */
922 942
923#if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC 943/* Use aligned_alloc if it or a simple substitute is available.
924# define USE_ALIGNED_ALLOC 1 944 Address sanitization breaks aligned allocation, as of gcc 4.8.2 and
945 clang 3.3 anyway. */
946
947#if ! ADDRESS_SANITIZER
948# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
949# define USE_ALIGNED_ALLOC 1
925/* Defined in gmalloc.c. */ 950/* Defined in gmalloc.c. */
926void *aligned_alloc (size_t, size_t); 951void *aligned_alloc (size_t, size_t);
927#elif defined HAVE_ALIGNED_ALLOC 952# elif defined HAVE_ALIGNED_ALLOC
928# define USE_ALIGNED_ALLOC 1 953# define USE_ALIGNED_ALLOC 1
929#elif defined HAVE_POSIX_MEMALIGN 954# elif defined HAVE_POSIX_MEMALIGN
930# define USE_ALIGNED_ALLOC 1 955# define USE_ALIGNED_ALLOC 1
931static void * 956static void *
932aligned_alloc (size_t alignment, size_t size) 957aligned_alloc (size_t alignment, size_t size)
933{ 958{
934 void *p; 959 void *p;
935 return posix_memalign (&p, alignment, size) == 0 ? p : 0; 960 return posix_memalign (&p, alignment, size) == 0 ? p : 0;
936} 961}
962# endif
937#endif 963#endif
938 964
939/* BLOCK_ALIGN has to be a power of 2. */ 965/* BLOCK_ALIGN has to be a power of 2. */
@@ -4553,16 +4579,8 @@ mark_maybe_pointer (void *p)
4553/* Mark Lisp objects referenced from the address range START+OFFSET..END 4579/* Mark Lisp objects referenced from the address range START+OFFSET..END
4554 or END+OFFSET..START. */ 4580 or END+OFFSET..START. */
4555 4581
4556static void 4582static void ATTRIBUTE_NO_SANITIZE_ADDRESS
4557mark_memory (void *start, void *end) 4583mark_memory (void *start, void *end)
4558#if defined (__clang__) && defined (__has_feature)
4559#if __has_feature(address_sanitizer)
4560 /* Do not allow -faddress-sanitizer to check this function, since it
4561 crosses the function stack boundary, and thus would yield many
4562 false positives. */
4563 __attribute__((no_address_safety_analysis))
4564#endif
4565#endif
4566{ 4584{
4567 void **pp; 4585 void **pp;
4568 int i; 4586 int i;
@@ -5477,7 +5495,7 @@ See Info node `(elisp)Garbage Collection'. */)
5477 stack_copy = xrealloc (stack_copy, stack_size); 5495 stack_copy = xrealloc (stack_copy, stack_size);
5478 stack_copy_size = stack_size; 5496 stack_copy_size = stack_size;
5479 } 5497 }
5480 memcpy (stack_copy, stack, stack_size); 5498 no_sanitize_memcpy (stack_copy, stack, stack_size);
5481 } 5499 }
5482 } 5500 }
5483#endif /* MAX_SAVE_STACK > 0 */ 5501#endif /* MAX_SAVE_STACK > 0 */