Здравствуйте, тут недавно заметил, что у меня после завершения процесса возникает утечка памяти в 8 кб. Начал разбираться в чем прикол, обнаружилось, что просто я забывал удалять директорий страниц, который был создан под процесс.
Вот так вот у меня устроены директории страниц:
Код:
typedef struct page_table
{
page_t pages[1024];
} page_table_t;
typedef struct page_directory
{
page_table_t *tables[1024];
uint32 tablesPhysical [1024];
uint32 physicalAddr;
} page_directory_t;
Соответсвенно для удаления директория написал такую функцию:
Код:
void destroy_directory (page_directory_t *src)
{
int i;
for (i = 0; i < 1024; i++)
{
if (!src->tables[i])
continue;
if (src->tables[i] != kernel_directory->tables[i])
kfree(src->tables[i]);
}
kfree (src);
}
Вот, вроде бы утечка памяти убралась, то есть после создания и умирания процессов вся память освобождается. НО!! При таком подходе система работает только в том случае, когда: создается процесс, убивается... Все работает! Но система перезагружается, если создам 2 процесса (для примера): создаю первый который запускается и умирает, после этого создаю процесс, который загружается и работает (не умирает!!!), делаю попытку создать второй такой процесс - система умирает.
Вот функции для копирования директории страниц:
Код:
static page_table_t *clone_table(page_table_t *src, uint32 *physAddr)
{
page_table_t *table = (page_table_t*)kmalloc_ap(sizeof(page_table_t), physAddr);
memset((uint8*)table, 0, sizeof(page_table_t));
int i;
for (i = 0; i < 1024; i++)
{
if (!src->pages[i].frame)
continue;
alloc_frame(&table->pages[i], 0, 0);
if (src->pages[i].present) table->pages[i].present = 1;
if (src->pages[i].rw) table->pages[i].rw = 1;
if (src->pages[i].user) table->pages[i].user = 1;
if (src->pages[i].accessed)table->pages[i].accessed = 1;
if (src->pages[i].dirty) table->pages[i].dirty = 1;
copy_page_physical(src->pages[i].frame*PAGE_SIZE, table->pages[i].frame*PAGE_SIZE);
}
return table;
}
page_directory_t *clone_directory(page_directory_t *src)
{
uint32 phys;
page_directory_t *dir = (page_directory_t*)kmalloc_ap(sizeof(page_directory_t), &phys);
memset((uint8*)dir, 0, sizeof(page_directory_t));
uint32 offset = (uint32)dir->tablesPhysical - (uint32)dir;
dir->physicalAddr = phys + offset;
int i;
for (i = 0; i < 1024; i++)
{
if (!src->tables[i])
continue;
if (kernel_directory->tables[i] == src->tables[i])
{
dir->tables[i] = src->tables[i];
dir->tablesPhysical[i] = src->tablesPhysical[i];
}
else
{
uint32 phys;
dir->tables[i] = clone_table(src->tables[i], &phys);
dir->tablesPhysical[i] = phys | 0x07;
}
}
return dir;
}
Поотлаживав я выяснил, что происходит ошибка в создании последнего запускаемого процесса при попытке копирования таблицы страниц... Все идет нормально, все правильно заполняется, но после вызова функции clone_table вся директория заполняется какими-то непонятными данными.
Не могу никак понять в чем тут может быть косяк...
Вот еще приведу функцию copy_page_physical:
Код:
copy_page_physical:
push ebx
pushf
cli
mov ebx, [esp+12]
mov ecx, [esp+16]
mov edx, cr0
and edx, 0x7fffffff
mov cr0, edx
mov edx, 1024
.loop:
mov eax, [ebx]
mov [ecx], eax
add ebx, 4
add ecx, 4
dec edx
jnz .loop
mov edx, cr0
or edx, 0x80000000
mov cr0, edx
popf
pop ebx
ret