Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Hi,
I'm having a problem with a free() function (stolen from PDClib), which seems to be causing my OS to pagefault. Is it possible if anyone can point out to me what is going wrong? (the error occurs in the free function itself: I've checked!)
This is the code for the function (located at 0x80000eff):
When I had a problem with page faults in my free() function I discovered that I was somehow overwriting the next pointer in the malloc block. Upon calling free it would look for a block somewhere where there was no memory mapped. Try just calling malloc and immediately calling free on that block and see if it causes a page fault.
edit: have you checked your support function for malloc() - the error is probably there... (and some bad coding practice for assuming malloc() does not return NULL)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
edit: have you checked your support function for malloc() - the error is probably there... (and some bad coding practice for assuming malloc() does not return NULL)
Heh - you can tell how inexperienced a coder I am, not checking that! Well, it seems that my alloc_pages function is returning a null value, and I don't see how that's possible: the code seems (on reading at least) watertight enough.
#define STD_HEAP_START 0xC0000000
#define STD_HEAP_PAGE_START (STD_HEAP_START/PAGE_SIZE)
static void *membreak; /*Where the heap ends*/
unsigned long membreak_page = 0;
void* alloc_pages(int const n)
{
void *oldbreak;
int i;
if(n>0)
{
/*if this is the first call:*/
if(membreak_page == 0)
{
membreak = (void *)STD_HEAP_START;
membreak_page = STD_HEAP_PAGE_START;
}
/*enable each page:*/
for(i=0; i<n; i++)
{
k_enable_memory(membreak_page);/*enable the memory at the end of the heap*/
membreak_page++; /*increase heap end*/
}
oldbreak = membreak; /*store the old heap end pointer*/
membreak = (void *)(membreak_page * PAGE_SIZE); /*update the heap end pointer*/
return(oldbreak); /*return the old heap end pointer (the beginning of the new block)*/
}
if(n<0)
{
/*if this is the first call, return error --> must have something to free!*/
if(membreak == 0)
return(0);
/*check the number of pages to free is not too high*/
if((membreak_page-n)<STD_HEAP_START)
return(0);
/*disable each page:*/
for(i=0; i>n; i--)
{
k_disable_memory(membreak_page);/*enable the memory at the end of the heap*/
membreak_page--; /*increase heap end*/
}
oldbreak = membreak; /*store the old heap end pointer*/
membreak = (void *)(membreak_page * PAGE_SIZE); /*update the heap end pointer*/
return(oldbreak); /*return the old heap end pointer (the beginning of the new block)*/
}
return(0);
}
Can you see what's going wrong here?
I really appreciate your help,
OScoder
What's the relationship between malloc and alloc_pages? If alloc_pages is an sbrk-like function, then it should _always_ return the old end-of-heap pointer, which you are correctly doing, as long as n != 0. The return should be (void *)-1 in the case of error. In the case of n == 0 you are returning 0 when you should return membreak, or (void *)-1 in the case that membreak == 0.
alloc_pages() is a helper function for pdclib - it passes a number of needed pages, and the function returns the base address where that memory is added.
I can't tell for sure, but it seems I have a different version of pdclib. You can check my implementation if you want.
but please, enable warnings (pass -Wall -Wextra -pedantic -Werror to gcc) to fix your sloppy coding practices, maybe that fixes the bug as well...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]