aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/alloc.c52
-rw-r--r--src/conf_post.h39
3 files changed, 87 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1e8684c4ddb..70df9cd3641 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12013-12-26 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix core dumps with gcc -fsanitize=address and GNU/Linux.
4 On my Fedora 19 platform the core dumps were so big that
5 my desktop became nearly catatonic.
6 * alloc.c (no_sanitize_memcpy) [MAX_SAVE_STACK > 0]: New function.
7 (Fgarbage_collect) [MAX_SAVE_STACK > 0]: Use it.
8 (USE_ALIGNED_MALLOC): Do not define if addresses are sanitized.
9 (mark_memory): Use ATTRIBUTE_NO_SANITIZE_ADDRESS rather than
10 a clang-only syntax.
11 * conf_post.h (__has_feature): New macro, if not already defined.
12 (ADDRESS_SANITIZER, ADDRESS_SANITIZER_WORKAROUND)
13 (ATTRIBUTE_NO_SANITIZE_ADDRESS): New macros.
14
12013-12-25 Eli Zaretskii <eliz@gnu.org> 152013-12-25 Eli Zaretskii <eliz@gnu.org>
2 16
3 * w32fns.c (Fw32_shell_execute): Make DOCUMENT absolute only if it 17 * w32fns.c (Fw32_shell_execute): Make DOCUMENT absolute only if it
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 */
diff --git a/src/conf_post.h b/src/conf_post.h
index 66dd9a36f00..04c4f4f5f15 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -50,8 +50,19 @@ typedef bool bool_bf;
50#endif 50#endif
51#endif 51#endif
52 52
53/* When not using Clang, assume its attributes and features are absent. */
53#ifndef __has_attribute 54#ifndef __has_attribute
54# define __has_attribute(a) false /* non-clang */ 55# define __has_attribute(a) false
56#endif
57#ifndef __has_feature
58# define __has_feature(a) false
59#endif
60
61/* True if addresses are being sanitized. */
62#if defined __SANITIZE_ADDRESS__ || __has_feature (address_sanitizer)
63# define ADDRESS_SANITIZER true
64#else
65# define ADDRESS_SANITIZER false
55#endif 66#endif
56 67
57#ifdef DARWIN_OS 68#ifdef DARWIN_OS
@@ -204,6 +215,32 @@ extern void _DebPrint (const char *fmt, ...);
204 215
205#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST 216#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST
206 217
218/* Work around GCC bug 59600: when a function is inlined, the inlined
219 code may have its addresses sanitized even if the function has the
220 no_sanitize_address attribute. This bug is present in GCC 4.8.2
221 and clang 3.3, the latest releases as of December 2013, and the
222 only platforms known to support address sanitization. When the bug
223 is fixed the #if can be updated accordingly. */
224#if ADDRESS_SANITIZER
225# define ADDRESS_SANITIZER_WORKAROUND NO_INLINE
226#else
227# define ADDRESS_SANITIZER_WORKAROUND
228#endif
229
230/* Attribute of functions whose code should not have addresses
231 sanitized. */
232
233#if (__has_attribute (no_sanitize_address) \
234 || 4 < __GNUC__ + (8 <= __GNUC_MINOR__))
235# define ATTRIBUTE_NO_SANITIZE_ADDRESS \
236 __attribute__ ((no_sanitize_address)) ADDRESS_SANITIZER_WORKAROUND
237#elif __has_attribute (no_address_safety_analysis)
238# define ATTRIBUTE_NO_SANITIZE_ADDRESS \
239 __attribute__ ((no_address_safety_analysis)) ADDRESS_SANITIZER_WORKAROUND
240#else
241# define ATTRIBUTE_NO_SANITIZE_ADDRESS
242#endif
243
207/* Some versions of GNU/Linux define noinline in their headers. */ 244/* Some versions of GNU/Linux define noinline in their headers. */
208#ifdef noinline 245#ifdef noinline
209#undef noinline 246#undef noinline