mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-09 08:56:15 +00:00
157 lines
3.2 KiB
C
157 lines
3.2 KiB
C
#include <unistd.h>
|
|
#include "tests/sys_mman.h"
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "../memcheck.h"
|
|
|
|
#define SUPERBLOCK_SIZE 100000
|
|
#define REDZONE_SIZE 8
|
|
|
|
static const int USE_MMAP = 0;
|
|
|
|
typedef struct _level_list
|
|
{
|
|
struct _level_list *next;
|
|
char *where;
|
|
// Padding ensures the struct is the same size on 32-bit and 64-bit
|
|
// machines.
|
|
char padding[16 - 2*sizeof(char*)];
|
|
} level_list;
|
|
|
|
typedef struct _pool {
|
|
char *mem;
|
|
char *where;
|
|
level_list *levels;
|
|
int size, left;
|
|
// Padding ensures the struct is the same size on 32-bit and 64-bit
|
|
// machines.
|
|
char padding[24 - 3*sizeof(char*)];
|
|
} pool;
|
|
|
|
pool *make_pool()
|
|
{
|
|
pool *p;
|
|
|
|
if(USE_MMAP) {
|
|
p = (pool *)mmap(0, sizeof(pool), PROT_READ|PROT_WRITE|PROT_EXEC,
|
|
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
|
p->where = p->mem = (char *)mmap(NULL, SUPERBLOCK_SIZE,
|
|
PROT_READ|PROT_WRITE|PROT_EXEC,
|
|
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
|
} else {
|
|
p = (pool *)malloc(sizeof(pool));
|
|
p->where = p->mem = (char *)malloc(SUPERBLOCK_SIZE);
|
|
}
|
|
|
|
p->size = p->left = SUPERBLOCK_SIZE;
|
|
p->levels = NULL;
|
|
(void) VALGRIND_MAKE_MEM_NOACCESS(p->where, SUPERBLOCK_SIZE);
|
|
return p;
|
|
}
|
|
|
|
void push(pool *p)
|
|
{
|
|
level_list *l;
|
|
|
|
if(USE_MMAP)
|
|
l = (level_list *)mmap(0, sizeof(level_list),
|
|
PROT_READ|PROT_WRITE|PROT_EXEC,
|
|
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
|
else
|
|
l = (level_list *)malloc(sizeof(level_list));
|
|
|
|
l->next = p->levels;
|
|
l->where = p->where;
|
|
VALGRIND_CREATE_MEMPOOL(l->where, REDZONE_SIZE, 0);
|
|
p->levels = l;
|
|
}
|
|
|
|
void pop(pool *p)
|
|
{
|
|
level_list *l = p->levels;
|
|
p->levels = l->next;
|
|
VALGRIND_DESTROY_MEMPOOL(l->where);
|
|
(void) VALGRIND_MAKE_MEM_NOACCESS(l->where, p->where-l->where);
|
|
p->where = l->where;
|
|
if(USE_MMAP)
|
|
munmap(l, sizeof(level_list));
|
|
else
|
|
free(l);
|
|
}
|
|
|
|
void destroy_pool(pool *p)
|
|
{
|
|
level_list *l = p->levels;
|
|
|
|
while(l) {
|
|
pop(p);
|
|
}
|
|
if(USE_MMAP) {
|
|
munmap(p->mem, SUPERBLOCK_SIZE);
|
|
munmap(p, sizeof(pool));
|
|
} else {
|
|
free(p->mem);
|
|
free(p);
|
|
}
|
|
}
|
|
|
|
char *allocate(pool *p, int size)
|
|
{
|
|
char *where;
|
|
p->left -= size + (REDZONE_SIZE*2);
|
|
where = p->where + REDZONE_SIZE;
|
|
p->where += size + (REDZONE_SIZE*2);
|
|
VALGRIND_MEMPOOL_ALLOC(p->levels->where, where, size);
|
|
return where;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Rest
|
|
//-------------------------------------------------------------------------
|
|
|
|
void test(void)
|
|
{
|
|
char *x1, *x2, *x3, *x4, *x5;
|
|
|
|
pool *p = make_pool();
|
|
|
|
push(p);
|
|
|
|
x1 = allocate(p, 10);
|
|
x2 = allocate(p, 20);
|
|
push(p);
|
|
x3 = allocate(p, 10);
|
|
x4 = allocate(p, 20);
|
|
|
|
*x1 = 'a'; // valid
|
|
*x2 = 'b'; // valid
|
|
|
|
x1[-1] = 'h'; // invalid
|
|
x1[10] = 'i'; // invalid
|
|
|
|
pop(p);
|
|
|
|
*x3 = 'c'; // invalid
|
|
*x4 = 'd'; // invalid
|
|
|
|
*x1 = 'e'; // valid
|
|
*x2 = 'f'; // valid
|
|
|
|
x5 = allocate(p, 10);
|
|
|
|
*x5 = 'g'; // valid
|
|
|
|
// pop(p);
|
|
|
|
// *x5 = 'g'; // invalid
|
|
|
|
// destroy_pool(p);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
test();
|
|
return 0;
|
|
}
|