Added a front and back wall to each kmalloc() allocation, if USE_WALL is
set to 1 (which it currently is). I've only used it with bochs yet, and it lets it crash reliably in some VFS code. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1261 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2c26aebcd8
commit
ebe92efe60
@ -15,14 +15,22 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define TRACE_HEAP 0
|
||||||
|
#if TRACE_HEAP
|
||||||
|
# define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
|
# define TRACE(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* prevent freeing pointers that were not allocated by kmalloc or are already freeed */
|
/* prevent freeing pointers that were not allocated by kmalloc or are already freeed */
|
||||||
#define PARANOID_POINTER_CHECK 1
|
#define PARANOID_POINTER_CHECK 1
|
||||||
/* initialize newly allocated memory with something non zero */
|
/* initialize newly allocated memory with something non zero */
|
||||||
#define PARANOID_KMALLOC 1
|
#define PARANOID_KMALLOC 1
|
||||||
/* check if freed pointers are already freed */
|
/* check if freed pointers are already freed */
|
||||||
#define PARANOID_KFREE 0
|
#define PARANOID_KFREE 1
|
||||||
/* print more debug infos in kmalloc and kfree */
|
/* use a back and front wall around each allocation */
|
||||||
#define MAKE_NOIZE 0
|
#define USE_WALL 1
|
||||||
|
|
||||||
|
|
||||||
// heap stuff
|
// heap stuff
|
||||||
// ripped mostly from nujeffos
|
// ripped mostly from nujeffos
|
||||||
@ -223,12 +231,16 @@ kmalloc(unsigned int size)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct heap_page *page;
|
struct heap_page *page;
|
||||||
|
|
||||||
#if MAKE_NOIZE
|
TRACE(("kmalloc: asked to allocate size %d\n", size));
|
||||||
dprintf("kmalloc: asked to allocate size %d\n", size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mutex_lock(&heap_lock);
|
mutex_lock(&heap_lock);
|
||||||
|
|
||||||
|
#if USE_WALL
|
||||||
|
// The wall uses 4 bytes to store the actual length of the requested
|
||||||
|
// block, 8 bytes for the front wall, and 8 bytes for the back wall
|
||||||
|
size += 20;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (bin_index = 0; bin_index < bin_count; bin_index++)
|
for (bin_index = 0; bin_index < bin_count; bin_index++)
|
||||||
if (size <= bins[bin_index].element_size)
|
if (size <= bins[bin_index].element_size)
|
||||||
break;
|
break;
|
||||||
@ -257,28 +269,40 @@ kmalloc(unsigned int size)
|
|||||||
bins[bin_index].alloc_count++;
|
bins[bin_index].alloc_count++;
|
||||||
page = &heap_alloc_table[((unsigned int)address - heap_base) / PAGE_SIZE];
|
page = &heap_alloc_table[((unsigned int)address - heap_base) / PAGE_SIZE];
|
||||||
page[0].free_count--;
|
page[0].free_count--;
|
||||||
#if MAKE_NOIZE
|
|
||||||
dprintf("kmalloc0: page 0x%x: bin_index %d, free_count %d\n", page, page->bin_index, page->free_count);
|
TRACE(("kmalloc0: page %p: bin_index %d, free_count %d\n", page, page->bin_index, page->free_count));
|
||||||
#endif
|
|
||||||
for(i = 1; i < bins[bin_index].element_size / PAGE_SIZE; i++) {
|
for(i = 1; i < bins[bin_index].element_size / PAGE_SIZE; i++) {
|
||||||
page[i].free_count--;
|
page[i].free_count--;
|
||||||
#if MAKE_NOIZE
|
TRACE(("kmalloc1: page 0x%x: bin_index %d, free_count %d\n", page[i], page[i].bin_index, page[i].free_count));
|
||||||
dprintf("kmalloc1: page 0x%x: bin_index %d, free_count %d\n", page[i], page[i].bin_index, page[i].free_count);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&heap_lock);
|
mutex_unlock(&heap_lock);
|
||||||
|
|
||||||
#if MAKE_NOIZE
|
TRACE(("kmalloc: asked to allocate size %d, returning ptr = %p\n", size, address));
|
||||||
dprintf("kmalloc: asked to allocate size %d, returning ptr = %p\n", size, address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PARANOID_KMALLOC
|
#if PARANOID_KMALLOC
|
||||||
memset(address,0xCC,size);
|
memset(address,0xCC,size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if USE_WALL
|
||||||
|
{
|
||||||
|
uint32 *wall = address;
|
||||||
|
wall[0] = size;
|
||||||
|
wall[1] = 0xabadcafe;
|
||||||
|
wall[2] = 0xabadcafe;
|
||||||
|
|
||||||
|
address = (uint8 *)address + 12;
|
||||||
|
size -= 20;
|
||||||
|
|
||||||
|
wall = (uint32 *)((uint8 *)address + size);
|
||||||
|
wall[0] = 0xabadcafe;
|
||||||
|
wall[1] = 0xabadcafe;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PARANOID_POINTER_CHECK
|
#if PARANOID_POINTER_CHECK
|
||||||
ptrchecklist_store(address);
|
ptrchecklist_store(address);
|
||||||
#endif
|
#endif
|
||||||
@ -300,6 +324,21 @@ kfree(void *address)
|
|||||||
if ((addr)address < heap_base || (addr)address >= (heap_base + heap_size))
|
if ((addr)address < heap_base || (addr)address >= (heap_base + heap_size))
|
||||||
panic("kfree: asked to free invalid address %p\n", address);
|
panic("kfree: asked to free invalid address %p\n", address);
|
||||||
|
|
||||||
|
#if USE_WALL
|
||||||
|
{
|
||||||
|
uint32 *wall = (uint32 *)((uint8 *)address - 12);
|
||||||
|
uint32 size = wall[0];
|
||||||
|
if (wall[1] != 0xabadcafe || wall[2] != 0xabadcafe)
|
||||||
|
panic("kfree: front wall was overwritten (allocation at %p, %lu bytes): %08lx %08lx\n", address, size, wall[1], wall[2]);
|
||||||
|
|
||||||
|
wall = (uint32 *)((uint8 *)address + size);
|
||||||
|
if (wall[0] != 0xabadcafe || wall[1] != 0xabadcafe)
|
||||||
|
panic("kfree: back wall was overwritten (allocation at %p, %lu bytes): %08lx %08lx\n", address, size, wall[0], wall[1]);
|
||||||
|
|
||||||
|
address = (uint8 *)address - 12;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PARANOID_POINTER_CHECK
|
#if PARANOID_POINTER_CHECK
|
||||||
if (!ptrchecklist_remove(address))
|
if (!ptrchecklist_remove(address))
|
||||||
panic("kfree: asked to free invalid pointer %p\n", address);
|
panic("kfree: asked to free invalid pointer %p\n", address);
|
||||||
@ -307,17 +346,13 @@ kfree(void *address)
|
|||||||
|
|
||||||
mutex_lock(&heap_lock);
|
mutex_lock(&heap_lock);
|
||||||
|
|
||||||
#if MAKE_NOIZE
|
TRACE(("kfree: asked to free at ptr = %p\n", address));
|
||||||
dprintf("kfree: asked to free at ptr = %p\n", address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
page = &heap_alloc_table[((unsigned)address - heap_base) / PAGE_SIZE];
|
page = &heap_alloc_table[((unsigned)address - heap_base) / PAGE_SIZE];
|
||||||
|
|
||||||
#if MAKE_NOIZE
|
TRACE(("kfree: page %p: bin_index %d, free_count %d\n", page, page->bin_index, page->free_count));
|
||||||
dprintf("kfree: page 0x%x: bin_index %d, free_count %d\n", page, page->bin_index, page->free_count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(page[0].bin_index >= bin_count)
|
if (page[0].bin_index >= bin_count)
|
||||||
panic("kfree: page %p: invalid bin_index %d\n", page, page->bin_index);
|
panic("kfree: page %p: invalid bin_index %d\n", page, page->bin_index);
|
||||||
|
|
||||||
bin = &bins[page[0].bin_index];
|
bin = &bins[page[0].bin_index];
|
||||||
|
Loading…
Reference in New Issue
Block a user