當我們調用malloc時先到libc函數中調用libc_malloc,__libc_malloc會先調用malloc_hook_init進行初始化,然後返回__libc_malloc,這時候會執行_init_malloc開始分配內存 ,定義在malloc.c中
我來分段分析
1
Void_t* public_mALLOc(size_t bytes) {
mstate ar_ptr;
Void_t *victim;
__malloc_ptr_t (*hook) (size_t, __const __malloc_ptr_t) =force_reg(__malloc_hook); if (__builtin_expect (hook != NULL, 0)) //如此可以發現檢查了hook函數是否爲空
return (*hook)(bytes, RETURN_ADDRESS (0)); //如果不是空就是調用這個函數
這裏首先會檢車hook函數是否爲NULL如果存在就調用並返回不存在就繼續執行
2
arena_lookup(ar_ptr);//在main_arena段尋找分配區指針
arena_lock(ar_ptr, bytes);
if(!ar_ptr) //找到就會調用_int_malloc()函數
return 0; //沒找到就返回
victim = _int_malloc(ar_ptr, bytes);
這裏就是在尋找分配區指針找到就調用_int_malloc函數分配內存沒有就結束malloc函數
if(!victim) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex);
victim = _int_malloc(ar_ptr, bytes);
(void)mutex_unlock(&ar_ptr->mutex);
這個是假如調用了_int_malloc函數但是沒有分配內存且不是在主分配區就會如果主分配區還能分配就會再次嘗試從主分配區分配內存,首先釋放分配區的鎖然後拿到鎖再次調用_int_malloc分配內存還有釋放鎖
3
} else { #if USE_ARENAS /* ... or sbrk() has failed and there is still a chance to mmap() */
ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); (void)mutex_unlock(&main_arena.mutex);
if(ar_ptr) {
victim = _int_malloc(ar_ptr, bytes);
(void)mutex_unlock(&ar_ptr->mutex);
}
這裏就是沒有分配成但是是主分配區的也就發生上面的操作
end
#endif } }
else (void)mutex_unlock(&ar_ptr->mutex); 如果_int_malloc()函數分配內存成功,釋放所使用的分配區的鎖。
assert(!victim || chunk_is_mmapped(mem2chunk(victim)) ||
ar_ptr == arena_for_chunk(mem2chunk(victim)));
return victim;
}
這裏我們終於通過_int_malloc申請到了內存我們就會釋放分配區的鎖,然後函數然後的是指向chunk的member的指針我們對申請的堆塊寫入,打印都是通過這個指針(victim)開心
read(0,(char*)victim,0x8);