Heap analysis/glibc 2.23
(glibc 2.23) free
lok2h4rd
2022. 3. 23. 15:11
힙의 할당한 메모리를 해제할 때 사용되는 함수이다
전체 코드 아래 더보기
더보기
void
__libc_free (void *mem)
{
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
void (*hook) (void *, const void *)
= atomic_forced_read (__free_hook);
if (__builtin_expect (hook != NULL, 0))
{
(*hook)(mem, RETURN_ADDRESS (0));
return;
}
if (mem == 0) /* free(0) has no effect */
return;
p = mem2chunk (mem);
if (chunk_is_mmapped (p)) /* release mmapped memory. */
{
/* see if the dynamic brk/mmap threshold needs adjusting */
if (!mp_.no_dyn_threshold
&& p->size > mp_.mmap_threshold
&& p->size <= DEFAULT_MMAP_THRESHOLD_MAX)
{
mp_.mmap_threshold = chunksize (p);
mp_.trim_threshold = 2 * mp_.mmap_threshold;
LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
mp_.mmap_threshold, mp_.trim_threshold);
}
munmap_chunk (p);
return;
}
ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, 0);
}
libc_hidden_def (__libc_free)
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
void (*hook) (void *, const void *)
= atomic_forced_read (__free_hook);
if (__builtin_expect (hook != NULL, 0))
{
(*hook)(mem, RETURN_ADDRESS (0));
return;
}
if (mem == 0) /* free(0) has no effect */
return;
변수 선언을 하고 malloc과 동일하게 __free_hook이 존재하는지 확인하고 있다면 호출한 뒤 리턴한다
free(0)인 경우 함수가 그대로 종료된다
p = mem2chunk (mem); //free할 주소의 헤더를 포함한 주소를 구함
if (chunk_is_mmapped (p)) // mmap으로 할당되었는지 확인
{
/* see if the dynamic brk/mmap threshold needs adjusting */
if (!mp_.no_dyn_threshold
&& p->size > mp_.mmap_threshold
&& p->size <= DEFAULT_MMAP_THRESHOLD_MAX)
{
mp_.mmap_threshold = chunksize (p);
mp_.trim_threshold = 2 * mp_.mmap_threshold;
LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
mp_.mmap_threshold, mp_.trim_threshold);
}
munmap_chunk (p);
return;
}
ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, 0);
mem2chunk를 통해 헤더를 포함한 주소를 구하고 mmap으로 할당되었는지 확인하다
ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, 0);
mmap으로 할당되지 않았으면 위의 코드가 시행되는데 p의 아레나를 구한 뒤 _int_free를 호출한다
_int_free에서는 실질적인 free의 역할을 수행하는 함수로 주요 동작은 아래와 같다
- p가 fastbin크기일 경우 fastbinY에 연결
- p가 fastbin크기가 아닐 경우 인접한 free된 청크와 병합
- 병합된 청크는 unsorted bin에 연결 및 병합될 청크 unlink수행
- 청크가 largebin 크기면 fd_nextsize, bk_nextszie NULL로 초기화
- size가 fastbin의 임계값보다 크고 fastbin에 청크가 있을때 fastbin을 병합 시킴
주요 함수 및 매크로
_int_free 링크글 - (glibc 2.23)