+2014-11-30 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port better to AddressSanitizer.
+ These changes suffice for temacs on x86-64 with GCC 4.9.2 and
+ -fsanitize=address.
+ * alloc.c (valid_pointer_p) [ADDRESS_SANITIZER]:
+ Return -1 or 0, as the pipe trick doesn't work.
+ * alloc.c (relocatable_string_data_p, mark_object, sweep_symbols):
+ * data.c (Ffset):
+ * print.c (print_object):
+ When a pointer-check primitive returns -1, do not assume this
+ means the pointer is valid or that the underlying system has failed.
+ It could just be that addresses are being sanitized so Emacs can't
+ test for pointer validity.
+ * lisp.h (defined_GC_CHECK_STRING_BYTES): New constant.
+ (USE_STACK_STRING) [GC_CHECK_STRING_BYTES]: Now false, since the
+ string validity checker doesn't work on stack-based strings.
+
2014-11-29 Paul Eggert <eggert@cs.ucla.edu>
Improve clarity of USE_LSB_TAG definition.
#ifdef WINDOWSNT
return w32_valid_pointer_p (p, 16);
#else
+
+ if (ADDRESS_SANITIZER)
+ return p ? -1 : 0;
+
int fd[2];
/* Obviously, we cannot just access it (we would SEGV trying), so we
return valid;
}
- return -1;
+ return -1;
#endif
}
struct sdata *sdata
= (struct sdata *) (str - offsetof (struct sdata, data));
- if (valid_pointer_p (sdata)
- && valid_pointer_p (sdata->string)
+ if (0 < valid_pointer_p (sdata)
+ && 0 < valid_pointer_p (sdata->string)
&& maybe_lisp_pointer (sdata->string))
return (valid_lisp_object_p
(make_lisp_ptr (sdata->string, Lisp_String))
CHECK_ALLOCATED_AND_LIVE (live_symbol_p);
ptr->gcmarkbit = 1;
/* Attempt to catch bogus objects. */
- eassert (valid_lisp_object_p (ptr->function) >= 1);
+ eassert (valid_lisp_object_p (ptr->function));
mark_object (ptr->function);
mark_object (ptr->plist);
switch (ptr->redirect)
++num_used;
sym->s.gcmarkbit = 0;
/* Attempt to catch bogus objects. */
- eassert (valid_lisp_object_p (sym->s.function) >= 1);
+ eassert (valid_lisp_object_p (sym->s.function));
}
}
/* Convert to eassert or remove after GC bug is found. In the
meantime, check unconditionally, at a slight perf hit. */
- if (valid_lisp_object_p (definition) < 1)
+ if (! valid_lisp_object_p (definition))
emacs_abort ();
set_symbol_function (symbol, definition);
# define USE_STACK_LISP_OBJECTS false
#endif
+#ifdef GC_CHECK_STRING_BYTES
+enum { defined_GC_CHECK_STRING_BYTES = true };
+#else
+enum { defined_GC_CHECK_STRING_BYTES = false };
+#endif
+
/* Struct inside unions that are typically no larger and aligned enough. */
union Aligned_Cons
USE_STACK_CONS = (USE_STACK_LISP_OBJECTS
&& alignof (union Aligned_Cons) % GCALIGNMENT == 0),
USE_STACK_STRING = (USE_STACK_CONS
+ && !defined_GC_CHECK_STRING_BYTES
&& alignof (union Aligned_String) % GCALIGNMENT == 0)
};
for (i = 0; i < limit; i++)
{
Lisp_Object maybe = area[i];
+ int valid = valid_lisp_object_p (maybe);
- if (valid_lisp_object_p (maybe) > 0)
+ if (0 < valid)
{
PRINTCHAR (' ');
print_object (maybe, printcharfun, escapeflag);
}
else
- strout (" <invalid>", -1, -1, printcharfun);
+ strout (valid ? " <some>" : " <invalid>",
+ -1, -1, printcharfun);
}
if (i == limit && i < amount)
strout (" ...", 4, 4, printcharfun);