Mercurial > emacs
changeset 32821:08e5ab6d998f
(state_protected_p, last_state_size, last_heapinfo)
[GC_MALLOC_CHECK && GC_PROTECT_MALLOC_STATE]: New variables.
(protect_malloc_state) [GC_MALLOC_CHECK &&
GC_PROTECT_MALLOC_STATE]: New function.
(PROTECT_MALLOC_STATE): New macro.
(__malloc_initialize, morecore, _malloc_internal)
(_free_internal) _realloc_internal): Use it to make _heapinfo
read-only outside of gmalloc.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Tue, 24 Oct 2000 12:41:02 +0000 |
parents | d78254659f1d |
children | 2b3e80a729bd |
files | src/gmalloc.c |
diffstat | 1 files changed, 68 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/gmalloc.c Tue Oct 24 12:40:08 2000 +0000 +++ b/src/gmalloc.c Tue Oct 24 12:41:02 2000 +0000 @@ -380,6 +380,53 @@ void (*__malloc_initialize_hook) PP ((void)); void (*__after_morecore_hook) PP ((void)); +#if defined GC_MALLOC_CHECK && defined GC_PROTECT_MALLOC_STATE + +/* Some code for hunting a bug writing into _heapinfo. + + Call this macro with argument PROT non-zero to protect internal + malloc state against writing to it, call it with a zero argument to + make it readable and writable. + + Note that this only works if BLOCKSIZE == page size, which is + the case on the i386. */ + +#include <sys/types.h> +#include <sys/mman.h> + +static int state_protected_p; +static __malloc_size_t last_state_size; +static malloc_info *last_heapinfo; + +void +protect_malloc_state (protect_p) + int protect_p; +{ + /* If _heapinfo has been relocated, make sure its old location + isn't left read-only; it will be reused by malloc. */ + if (_heapinfo != last_heapinfo + && last_heapinfo + && state_protected_p) + mprotect (last_heapinfo, last_state_size, PROT_READ | PROT_WRITE); + + last_state_size = _heaplimit * sizeof *_heapinfo; + last_heapinfo = _heapinfo; + + if (protect_p != state_protected_p) + { + state_protected_p = protect_p; + if (mprotect (_heapinfo, last_state_size, + protect_p ? PROT_READ : PROT_READ | PROT_WRITE) != 0) + abort (); + } +} + +#define PROTECT_MALLOC_STATE(PROT) protect_malloc_state(PROT) + +#else +#define PROTECT_MALLOC_STATE(PROT) /* empty */ +#endif + /* Aligned allocation. */ static __ptr_t align PP ((__malloc_size_t)); @@ -492,6 +539,7 @@ register_heapinfo (); __malloc_initialized = 1; + PROTECT_MALLOC_STATE (1); return 1; } @@ -516,6 +564,8 @@ if (result == NULL) return NULL; + PROTECT_MALLOC_STATE (0); + /* Check if we need to grow the info table. */ if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize) { @@ -599,6 +649,7 @@ it can relocate or resize the info table. */ _heaplimit = 0; _free_internal (oldinfo); + PROTECT_MALLOC_STATE (0); /* The new heap limit includes the new table just allocated. */ _heaplimit = BLOCK ((char *) newinfo + heapsize * sizeof (malloc_info)); @@ -632,6 +683,8 @@ return NULL; #endif + PROTECT_MALLOC_STATE (0); + if (size < sizeof (struct list)) size = sizeof (struct list); @@ -680,11 +733,15 @@ and break it into fragments, returning the first. */ #ifdef GC_MALLOC_CHECK result = _malloc_internal (BLOCKSIZE); + PROTECT_MALLOC_STATE (0); #else result = malloc (BLOCKSIZE); #endif if (result == NULL) - return NULL; + { + PROTECT_MALLOC_STATE (1); + return NULL; + } /* Link all fragments but the first into the free list. */ next = (struct list *) ((char *) result + (1 << log)); @@ -803,6 +860,7 @@ _heapinfo[block + blocks].busy.info.size = -blocks; } + PROTECT_MALLOC_STATE (1); return result; } @@ -913,6 +971,8 @@ if (ptr == NULL) return; + PROTECT_MALLOC_STATE (0); + for (l = _aligned_blocks; l != NULL; l = l->next) if (l->aligned == ptr) { @@ -1035,6 +1095,7 @@ /* Allocate new space for the info table and move its data. */ newinfo = (malloc_info *) _malloc_internal (info_blocks * BLOCKSIZE); + PROTECT_MALLOC_STATE (0); memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); _heapinfo = newinfo; @@ -1133,6 +1194,8 @@ } break; } + + PROTECT_MALLOC_STATE (1); } /* Return memory to the heap. */ @@ -1296,6 +1359,8 @@ block = BLOCK (ptr); + PROTECT_MALLOC_STATE (0); + type = _heapinfo[block].busy.type; switch (type) { @@ -1344,6 +1409,7 @@ _heaplimit = 0; _free_internal (ptr); result = _malloc_internal (size); + PROTECT_MALLOC_STATE (0); if (_heaplimit == 0) _heaplimit = oldlimit; if (result == NULL) @@ -1387,6 +1453,7 @@ break; } + PROTECT_MALLOC_STATE (1); return result; }