Fix crashes in lisp_align_free in a build with GC_MCHECK.
src/gmalloc.c (aligned_alloc): Fix adjustment of size of the allocated buffer due to alignment. (freehook): If the block to be freed was allocated by 'aligned_alloc', find its real pointer before calling 'free'. (mabort) [emacs]: Call 'emacs_abort', not 'abort', to provide a backtrace. Fixes: debbugs:16901
This commit is contained in:
parent
19dae293f9
commit
bd650c2420
2 changed files with 36 additions and 2 deletions
|
@ -1,3 +1,13 @@
|
|||
2014-03-03 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* gmalloc.c (aligned_alloc): Fix adjustment of size of the
|
||||
allocated buffer due to alignment.
|
||||
(freehook): If the block to be freed was allocated by
|
||||
'aligned_alloc', find its real pointer before calling 'free'.
|
||||
(Bug#16901)
|
||||
(mabort) [emacs]: Call 'emacs_abort', not 'abort', to provide a
|
||||
backtrace.
|
||||
|
||||
2014-03-03 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* font.c (toplevel): Adjust comment about font cache layout.
|
||||
|
|
|
@ -68,6 +68,10 @@ extern int posix_memalign (void **, size_t, size_t);
|
|||
extern void malloc_enable_thread (void);
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
extern void emacs_abort (void);
|
||||
#endif
|
||||
|
||||
/* The allocator divides the heap into blocks of fixed size; large
|
||||
requests receive one or more whole blocks, and small requests
|
||||
receive a fragment of a block. Fragment sizes are powers of two,
|
||||
|
@ -1595,7 +1599,7 @@ aligned_alloc (size_t alignment, size_t size)
|
|||
{
|
||||
/* Reallocate the block with only as much excess as it needs. */
|
||||
free (result);
|
||||
result = malloc (adj + size);
|
||||
result = malloc (size + alignment - adj);
|
||||
if (result == NULL) /* Impossible unless interrupted. */
|
||||
return NULL;
|
||||
|
||||
|
@ -1605,7 +1609,7 @@ aligned_alloc (size_t alignment, size_t size)
|
|||
different block with weaker alignment. If so, this block is too
|
||||
short to contain SIZE after alignment correction. So we must
|
||||
try again and get another block, slightly larger. */
|
||||
} while (adj > lastadj);
|
||||
} while (adj < lastadj);
|
||||
|
||||
if (adj != 0)
|
||||
{
|
||||
|
@ -1787,6 +1791,22 @@ freehook (void *ptr)
|
|||
|
||||
if (ptr)
|
||||
{
|
||||
struct alignlist *l;
|
||||
|
||||
/* If the block was allocated by aligned_alloc, its real pointer
|
||||
to free is recorded in _aligned_blocks; find that. */
|
||||
PROTECT_MALLOC_STATE (0);
|
||||
LOCK_ALIGNED_BLOCKS ();
|
||||
for (l = _aligned_blocks; l != NULL; l = l->next)
|
||||
if (l->aligned == ptr)
|
||||
{
|
||||
l->aligned = NULL; /* Mark the slot in the list as free. */
|
||||
ptr = l->exact;
|
||||
break;
|
||||
}
|
||||
UNLOCK_ALIGNED_BLOCKS ();
|
||||
PROTECT_MALLOC_STATE (1);
|
||||
|
||||
hdr = ((struct hdr *) ptr) - 1;
|
||||
checkhdr (hdr);
|
||||
hdr->magic = MAGICFREE;
|
||||
|
@ -1878,7 +1898,11 @@ mabort (enum mcheck_status status)
|
|||
#else
|
||||
fprintf (stderr, "mcheck: %s\n", msg);
|
||||
fflush (stderr);
|
||||
# ifdef emacs
|
||||
emacs_abort ();
|
||||
# else
|
||||
abort ();
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue