ptmalloc堆数据结构

本文详细介绍了glibc中的ptmalloc堆数据结构,包括Chunk、Bins、Fast bin、Small bin、Large bin、unsorted bin等概念,以及多线程数据结构的相关信息,如Heap Header和Arena header。内容涵盖内存对齐、Chunk大小计算、Bin定位、Fastbin的管理等核心知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

glibc-2.3.x. 之后,glibc 中集成了ptmalloc2

 

可以下载glibc源码查看ptmalloc

http://ftp.gnu.org/gnu/glibc/

 

查看glibc版本

millionsky@ubuntu-16:~/tmp$ ldd --version

ldd (Ubuntu GLIBC 2.23-0ubuntu9) 2.23

 

这里主要参考:

https://ctf-wiki.github.io/ctf-wiki/pwn/heap

 

本文参考的glibc源码是glibc-2.25.tar.xz

ptmalloc堆数据结构

2.1 Chunk

2.1.1 Malloc_chunk

struct malloc_chunk {

 

INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk (if free). */

INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */

 

struct malloc_chunk *fd; /* double links -- used only if free. */

struct malloc_chunk *bk;

 

/* Only used for large blocks: pointer to next larger size. */

struct malloc_chunk *fd_nextsize; /* double links -- used only if free. */

struct malloc_chunk *bk_nextsize;

};

2.1.2 尺寸定义

#ifndef INTERNAL_SIZE_T

# define INTERNAL_SIZE_T size_t

#endif

 

/* The corresponding word size. */

#define SIZE_SZ (sizeof (INTERNAL_SIZE_T))

 

l INTERNAL_SIZE_Tsize_t32/64位整数

l SIZE_SZ32/64

2.1.3 Chunk的对齐

/* MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks. It

must be a power of two at least 2 * SIZE_SZ, even on machines for

which smaller alignments would suffice. It may be defined as larger

than this though. Note however that code and data structures are

optimized for the case of 8-byte alignment. */

#ifndef MALLOC_ALIGNMENT

# define MALLOC_ALIGNMENT (2 * SIZE_SZ < __alignof__ (long double) \

? __alignof__ (long double) : 2 * SIZE_SZ)

#endif

 

/* The corresponding bit mask value. */

#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)

 

l MALLOC_ALIGNMENT:对齐字节,8/16

注意:如果64位上size_t4字节,则对齐为8

l MALLOC_ALIGN_MASK:对齐掩码,0x7/0x0f

 

l 检查分配给用户的内存是否对齐

aligned_OK(m)判断m是否对齐;

misaligned_chunk(p)p转换为对齐后的地址(向下取整);

/* Check if m has acceptable alignment */

 

#define aligned_OK(m) (((unsigned long)(m) & MALLOC_ALIGN_MASK) == 0)

 

#define misaligned_chunk(p) \

((uintptr_t)(MALLOC_ALIGNMENT == 2 * SIZE_SZ ? (p) : chunk2mem (p)) \

& MALLOC_ALIGN_MASK)

2.1.4 最小chunk

l Chunk的最小尺寸:16/32

最小的chunk包含前面4个字段;

/* The smallest possible chunk */

#define MIN_CHUNK_SIZE (offsetof(struct malloc_chunk, fd_nextsize))

 

注意:如果64位上size_t4字节,则最小的chunk24字节

 

最小malloc size

最小的malloc size是对齐后的最小chunk,大小为16/32

 

注意:如果64位上size_t4字节,则MINSIZE32。此时MIN_CHUNK_SIZE24)和MINSIZE不一致。

 

/* The smallest size we can malloc is an aligned minimal chunk */

 

#define MINSIZE \

(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))

2.1.5 Malloc header<-->user pointer

Allocated chunk的前两个字段称为 chunk header/malloc header,后面的部分称为user data。转换只要移动chunk header即可,即8/16字节;

 

/* conversion from malloc headers to user pointers, and back */

 

#define chunk2mem(p) ((void*)((char*)(p) + 2*SIZE_SZ))

#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))

 

2.1.6 用户大小检查与转换

l REQUEST_OUT_OF_RANGE:判断请求字节是否超出范围

MINSIZE16/32

则最大的请求大小不能超过0xFFFF FFE0/0xFFFF FFFF FFFF FFC0

这里为了简化某些代码,边界制定得比较低,即时加上MINSIZE,也不好回绕0

/*

Check if a request is so large that it would wrap around zero when

padded and aligned. To simplify some other code, the bound is made

low enough so that adding MINSIZE will also not wrap around zero.

*/

 

#define REQUEST_OUT_OF_RANGE(req) \

((unsigned long) (req) >=            \

(unsigned long) (INTERNAL_SIZE_T) (-2 * MINSIZE))

l request2size

Request2size:将用户请求的大小转换为对齐后的chunk大小

MALLOC_ALIGNMENT至少是2*SIZE_SZ,这里会补齐chunk header然后对齐。

 

/* pad request bytes into a usable size -- internal version */

 

#define request2size(req) \

(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \

MINSIZE : \

((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)

 

/* Same, except also perform argument check */

 

#define checked_request2size(req, sz) \

if (REQUEST_OUT_OF_RANGE (req)) {          \

__set_errno (ENOMEM);            \

return 0;                \

}                  \

(sz) = request2size (req);

 

l checked_request2size:先检查范围再进行大小转换

#define checked_request2size(req, sz) \

if (REQUEST_OUT_OF_RANGE (req)) {          \

__set_errno (ENOMEM);            \

return 0;                \

}                  \

(sz) = request2size (req);

2.1.7 标记相关

P标记:

/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */

#define PREV_INUSE 0x1

 

/* extract inuse bit of previous chunk */

#define prev_inuse(p) ((p)->mchunk_size & PREV_INUSE)

 

M标记:

/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */

#define IS_MMAPPED 0x2

 

/* check for mmap()'ed chunk */

#define chunk_is_mmapped(p) ((p)->mchunk_size & IS_MMAPPED)

 

A标记

/* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained

from a non-main arena. This i

本文通过Glibc的内存暴增问题,主要介绍了系统的内存管理问题,具体如下: 目录 1. 问题 2. 基础知识 2.1 X86平台Linux进程内存布局 2.1.1 32位模式下进程内存经典布局 2.1.2 32位模式下进程默认内存布局 2.1.3 64位模式下进程内存布局 2.2 操作系统内存分配的相关函数 2.2.1 Heap操作相关函数 2.2.2 Mmap映射区域操作相关函数 3. 概述 3.1 内存管理一般性描述 3.1.1 内存管理的方法 3.1.2 内存管理器的设计目标 3.1.3 常见C内存管理程序 3.2 Ptmalloc内存管理概述 3.2.1 简介 3.2.2 内存管理的设计假设 3.2.3 内存管理数据结构概述 3.2.4 内存分配概述 3.2.5 内存回收概述 3.2.6 配置选项概述 3.2.7 使用注意事项 4. 问题分析及解决 5. 源代码分析 5.1 边界标记法 5.2 分箱式内存管理 5.2.1 Small bins 5.2.2 Large bins 5.2.3 Unsorted bin 5.2.4 Fast bins 5.3 核心结构体分析 5.3.1 malloc_state 5.3.2 Malloc_par 5.3.3 分配区的初始化 5.4 配置选项 5.5 Ptmalloc的初始化 5.5.1 Ptmalloc未初始化时分配/释放内存 5.5.2 ptmalloc_init()函数 5.5.3 ptmalloc_lock_all(),ptmalloc_unlock_all(),ptmalloc_unlock_all2() 5.6 多分配区支持 5.6.1 Heap_info 5.6.2 获取分配区 5.6.3 Arena_get2() 5.6.4 _int_new_arena() 5.6.5 New_heap() 5.6.6 get_free_list()和reused_arena() 5.6.7 grow_heap(),shrink_heap(),delete_heap(),heap_trim() 5.7 内存分配malloc 5.7.1 public_mALLOc() 5.7.2 _int_malloc() 5.8 内存释放free 5.8.1 Public_fREe() 5.8.2 _int_free() 5.8.3 sYSTRIm()和munmap_chunk(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值