执行free进入_int_free函数
检查,如果free的地址p大于(uintptr_t) -size或者p不是0x10对齐的,报错”free(): invalid pointer”
如果根据p获取到的size,小于0x20或者size不是8字节对齐,则报错”free(): invalid size”
检查下一个size的prev_inuse位
进入free 进入tcache的流程
- 根据size获取tc_idx
- 如果tcache已经初始化,并且tc_idx< mp_.tcache_bins
- 获取p指向堆块的头,p原来指的是0x10偏移的位置,这个地址为e
- 如果e的key等于tcache_key(一个随机数),就进入检查
- 循环遍历该tcache,如果循环计数器cnt大于mp_.tcache_count每个tcache存放堆块的最大个数,报错”free(): too many chunks detected in tcache”
- 如果tcache里有堆块没对齐,报错”free(): unaligned chunk detected in tcache 2”
- 如果e等于tmp,就是存在两个相同堆块,报错”free(): double free detected in tcache 2”
- 如果对应tc_idx的tcache没满,放入tcache,返回
进入free进入fastbin的流程
- 如果size,小于等于MAX_FAST,并且p的下一个堆块不是top
- 检查,如果下一个堆块的size小于0x10或者大于av->system_mem,则报错”free(): invalid next size (fast)”
- 让av->have_fastchunks变为true
- 根据size获取对应的fastbin的idx
- 获取对应fastbin的地址,fb
- 获取fastbin最后放入的堆块,为old
- 如果释放的和old是同一个堆块,报错”double free or corruption (fasttop)”
- 加密释放堆块的fd
- 放入fastbin
- 如果size,小于等于MAX_FAST,并且p的下一个堆块不是top
否则如果不是mmap的堆块,进入_int_free_merge_chunk函数
- 根据size,获取p的nextchunk
- 如果p是topchunk,报错”double free or corruption (top)”
- 如果arena是sbrk分配的,并且nextchunk的地址>av->top加上top的size,报错”double free or corruption (out)”
- 如果下一个堆块的pre_inuse为0,报错”double free or corruption (!prev)”
- 如果下一个堆块的size<0x10或者下一个堆块的size>=av->system_mem,报错”free(): invalid next size (normal)”
- 进行向后合并
- 如果p的prev_inuse为0
- 获取p的prev_size,为prevsize
- 根据prevsize更新p为上一个堆块
- 如果现在的p的size,与刚刚保存的prev_size不同,报错”corrupted size vs. prev_size while consolidating”
- unlink现在的p
- 如果堆块的size位不等于(根据size找到的)下一个堆块的pre_size 报错 “corrupted size vs. prev_size”
- 更新fd为p的fd,bk为p的bk
- 如果fd->bk!=p或者bk->fd!=p报错”corrupted double-linked list”
- 执行fd和bk的unlink过程
- fd->bk = bk;
- bk->fd = fd;
- 如果这个堆块不属于small bin的大小范围,并且这个堆块的fd_nextsize不等于NULL,则会进入unlink largebin的过程
- 如果p->fd_nextsize->bk_nextsize != p或者p->bk_nextsize->fd_nextsize != p报错”corrupted double-linked list (not small)”
- 如果fd->fd_nextsize == NULL
- 如果p->fd_nextsize == p
- fd->fd_nextsize = fd->bk_nextsize = fd;
- 否则
- fd->fd_nextsize = p->fd_nextsize;
- fd->bk_nextsize = p->bk_nextsize;
- p->fd_nextsize->bk_nextsize = fd;
- p->bk_nextsize->fd_nextsize = fd;
- 如果p->fd_nextsize == p
- 否则
- p->fd_nextsize->bk_nextsize = p->bk_nextsize;
- p->bk_nextsize->fd_nextsize = p->fd_nextsize;
如果是mmap的堆块,munmap它
Thanks for reading!
