I try to implement a toy malloc,and my code crashed at
list_head = header
in
#define ADDR_ADD(a, o) (((char*)(a)) + o)
#define HEADER_SIZE (sizeof(heap_header))
static heap_header* list_head = NULL;
int mini_crt_heap_init()
{
void* base = NULL;
heap_header* header = NULL;
unsigned heap_size = 1024 * 1024 * 32;
base = (void*)brk(0);
void* end = ADDR_ADD(base, heap_size);
end = (void*)brk(end);
if(!end) return 0;
header = (heap_header*)base;
header->size = heap_size;
header->type = HEAP_BLOCK_FREE;
header->next = NULL;
header->prev = NULL;
list_head = header;
return 1;
}
In GDB,the pointer header gets the value of the pointer base, and I also make some assignments on header and they all work. However, when it goes to list_head = header,the program crashed.
The screenshot of gdb: base,end,header and list_head
My question is that if I can't access the address,it should crash at header->size = heap_size;, which is a normal segfault. But it goes well until list_head = header;
I haven't got any idea why segmentation fault occurred, and how can I handle this problem and make it run? Is there any problem with my makefile?
The struct of heap_header:
typedef struct _heap_header
{
enum{
HEAP_BLOCK_FREE = 0xABABABAB,
HEAP_BLOCK_USED = 0xCDCDCDCD,
} type;
unsigned size;
struct _heap_header *next;
struct _heap_header *prev;
}heap_header;
My brk():
//Linux brk system call
static int brk(void* end_data_segment)
{
int ret = 0;
asm("movl $45, %%eax \n\t"
"movl %1 , %%ebx \n\t"
"int $0x80 \n\t"
"movl %%eax, %0 \n\t"
: "=m"(ret)
: "m"(end_data_segment)
);
return ret;
}
Additional makefile
STATIC_SRC = malloc.c stdio.c string.c
STATIC_OBJ = $(patsubst %.c,%.o,$(STATIC_SRC))
CFLAGS = -c -fno-builtin -nostdlib -fno-stack-protector -m32
static:
gcc -g $(CFLAGS) $(STATIC_SRC) entry.c
ar -rs minicrt.a $(STATIC_OBJ)
test:
gcc -g $(CFLAGS) test.c
ld -static -melf_i386 -e mini_crt_entry entry.o test.o minicrt.a -o test
all: static test
clean:
rm -f *.o *.a test core*