ptmalloc | free 总体流程简述 | 无原子优化相关

当前流程 不考虑 开启原子优化

Public_fREe(void *mem)

  • __free_hook == null ? pass : __free_hook(mem) # 如果 __free_hook 不为 null , 调用 __free_hook
  • mem == null ? return; : mem2chunk(mem) => p; # 检测 mem 是否为 null , 如果为null , 直接return , 无影响
  • if HAVE_MMAP # 检测 HAVE_MMAP 标识符
    • chunk_is_mmaped(p) # 检测是否是 mmap 分配的
      • !mp_.no_dyn_threshold && p->size > mp_.mmap_threshold && p->size <= DEFAULT_MMAP_THRESHOLD_MAX # 检测 动态调整 mmap_threshold 是否开启 和 条件是否满足 ([mp_,mmap_threshold + 1 , DEFAULT_MMAP_THRESHOLD_MAX ])
      • mp_.mmap_threshold = chunksize (p); # 调整 分配阈值为 chunksize(p)
        • mp_.trim_threshold = 2 * mp_.mmap_threshold # 调整 收缩阈值
    • munmap_chunk(p) # 解除映射
  • ar_ptr = arena_for_chunk(p); # 根据 chunk 获取 arena 的指针
  • 对 分配区 尝试加锁
  • _int_free(ar_ptr, p); # 调用 _int_free 执行实际的释放工作
  • 对 分配去 解锁

_int_free(mstate av, mchunkptr p)

  • 检测1 : p > -size || (misaligned_chunk (p)
    • 报错标志 : free(): invalid pointer
    • 检测内容 : 指针地址是否溢出 , 指针的地址 是否对齐
    • 相关参数 :
      • size = chunksize(p)
  • 检测2 : size < MINSIZE
    • 报错标志 : free(): invalid size
    • 检测内容 : chunk size 是否 大于 MINSIZE
    • 相关参数:
      • size = chunksize(p)
  • size <= get_max_fast () # fastbin chunk
    • if TRIM_FASTBINS # 检测 TRIM_FASTBINS 标识符
      • 作用 : 如果该标识符为 True , 靠近 top chunk 的 fastbin 不会进入该逻辑进行处理
    • 检测 1: chunk_at_offset (p, size)->size <= 2 * SIZE_SZ || chunksize (chunk_at_offset (p, size)) >= av->system_mem
      • 报错标志: free(): invalid next size (fast)
      • 检测内容 : 下一个 chunk 的 size 是否 <= MINSIZE 或者 大于 分配内存总量
    • 检测 2 : *fb == p
      • 报错标志 : double free or corruption (fasttop)
      • 检测内容 : 对应大小的 fastbin 链表表头 的 chunk 和 即将要 free 的 chunk 是否相同 , 即 double free # 这里是 fastbin attack 中 double free 的 利用原理
      • 相关参数 :
        • unsigned int idx = fastbin_index(size)
        • fb = &fastbin (av, idx)
    • 检测 3 : fb != NULL && fastbin_index(chunksize(fb)) != idx
      • 报错标志 : invalid fastbin entry (free)
      • 检测内容 : 检测 对应fastbin 的 idx 和 p 的 idx 是否相同
      • 相关参数 :
        • unsigned int idx = fastbin_index(size)
        • fb = &fastbin (av, idx)
    • 加入 链表表头
      • fd | *next
      • LIFO | 后进先出
  • if chunk_is_mmapped(p) : | mmap 分配的 chunk # 原为 else 的 处理 ,在最下方
    - munmap_chunk (p); | 使用 munmap_chunk 解除映射
  • if !chunk_is_mmapped(p) : # 不是 mmap 分配的 chunk # 此处 是原代码的判断 , 为了便于查看 , 将 mmap 分配内存的处理调整到 上方
    • 检测 1 : p == av->top
      • 报错标志 : double free or corruption (top)
      • 检测内容 : p 是否是 top chunk
    • 检测 2 : next_chunk >= av->top + chunksize(av->top)
      • 报错标志 : double free or corruption (out)
      • 检测内容 : next_chunk 是否超过了 main_arena 的 范围 , 地址溢出?
      • 相关参数 :
        • nextchunk = chunk_at_offset(p , size)
    • 检测 3 : !prev_inuse(next_chunk)
      • 报错标志 : double free or corruption (!prev)
      • 检测内容 : 检测当前 chunk 是否正在使用
      • 相关参数 :
        • nextchunk = chunk_at_offset(p , size)
    • 检测 4 : nextchunk->size <= 2 * SIZE_SZ || nextsize >= av->system_mem
      • 报错标志 : free(): invalid next size (normal)
      • 检测内容 : 检测下一个 chunk 的大小是否在合理范围内 [ 2 * SIZE_SZ : av->system_mem]
      • 相关参数 :
        • nextsize = chunksize(nextchunk)
        • nextchunk = chunk_at_offset(p , size)
    • consolidate forward | 前向合并
      • 前置条件 : !prev_inuse(p) # 检测 前一个 chunk 是否在使用中
      • 操作过程 :
        • prevsize = p->prev_size
        • size += prevsize # 增加 size 的 长度
        • p = chunk_at_offset(p , - prevsize) # 设置 p 的 新位置
        • unlink(p , bck , fwd) # unlink 操作 , 将前一个 chunk 从空闲 chunk 链表中移除
      • consolidate backward | 后向合并
      • 前置条件 : nextchunk != av->top && !nextinuse # 检测 下一个 chunk 是不是 topchunk 并且下一个 chunk 空闲
        • 相关参数 :
          • nextchunk = chunk_at_offset(p , size)
          • nextinuse = inuse_bit_at_offset(nextchunk, nextsize) | 获取 nextchunk 的使用状态
        • 操作过程:
        • unlink(nextchunk, bck, fwd) | unlink 下一个chunk
        • size += nextsize
      • else :# 下一个 chunk 不空闲
        • clear_inuse_bit_at_offset(nextchunk, 0) # 设置当前 chunk 的使用状态为 空闲
    • if nextchunk != av->top : # 下一个 chunk 不是 top chunk 时 , 放入 unsorted bin
      • 检测 1 : fwd->bk != bck
        • 报错标志 : free(): corrupted unsorted chunks
        • 检测内容 : 检测 unsorted_bin 的第一个 chunk 的bk 是否指向 &unsorted_bin_list
        • 相关参数 :
          • bck = unsorted_chunks(av)
          • fwd = bck->fd
      • 放入链表尾部:
        • 操作 :
            1. p->fd = fwd; p->bk = bck; | unsorted bin attack 的原理
            1. bck->fd = p;fwd->bk = p;
              • if !in_smallbin_range(size) | large bin
                • p->fd_nextsize = NULL; p->bk_nextsize = NULL
            1. set_head(p, size | PREV_INUSE); # 设置 p 的 size 域
            1. set_foot(p, size) # 设置 p 的 next_chunk 的 prev_size
    • else: # 下一个 chunk 是 top chnk
      • size += nextsize | size 加上 topchunk的size
      • av-top = p | 将 top chunk 的地址 设置为 p
    • if (size) >= FASTBIN_CONSOLIDATION_THRESHOLD | 如果合并后 size > fastbin 整合的阈值
      • if hava_fastchunks(av) | 如果 有 fastbin chunk
      • malloc_consolidate(av) | 对fastbin chunks 进行一次整合 , 整合 fastbin chunk 到 unsorted bin 中
        • if (av == &main_arena) | 判断 当前 arena 是不是主分配区
          • if ( chunksize(av->top) > mp_.trim_threshold) | 判断 top chunk 的大小是否超过了heap 的收缩阈值
          • sYSTRIm(mp_.top_pad , av) | 调用 sYSTRIm 进行收缩
        • else : | 非主分配区
        • heap_info *heap = heap_for_ptr(top(av));
        • assert(heap->ar_ptr == av);
        • heap_trim(heap, mp_.top_pad); | 尝试用 heap_trim 收缩 子分配区
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 今天学习了下house_of_orange,总算是把house_of_orange给搞懂了house_of_ora...
    zs0zrc阅读 3,526评论 0 1
  • Linux内存空间简介 32位Linux平台下进程虚拟地址空间分布如下图: Linux提供了如下几个系统调用,用于...
    90后老码农阅读 11,431评论 2 14
  • 大海啊, 你为何咆哮, 朝阳印在你的脸颊, 我静静地站在彼岸, 向你投掷甜美的微笑。 大海啊, 你为何咆哮, 轻风...
    夜雨梧桐风阅读 172评论 0 1
  • 今天去医院了,想把心补补,医生看了一下说,伤的太厉害了,没法补了,还是把它取了吧! 我说行吧。 医生又来一句,说:...
    不如怀念9527阅读 93评论 0 0
  • 寒山问佛陀,世间痴男怨女几何?佛说:意中人、执念、相思、遗恨。 寒山道:意中人何解?佛曰:红豆。 执念何解?清风。...
    简小竹阅读 568评论 5 3