个人网站建立 学生,重庆手机网站制作费用,广东模板建站平台,建设工程公司简介模板1 使用场景
在Postgresql的内存管理模块中#xff0c;最常用的aset.c提供的内存池实现#xff0c;该实现提供了两个非常实用的开关来解决常见的内存越界问题#xff1a;
memdebug.c * About CLOBBER_FREED_MEMORY:** If this symbol is defined, all freed memory is over…1 使用场景
在Postgresql的内存管理模块中最常用的aset.c提供的内存池实现该实现提供了两个非常实用的开关来解决常见的内存越界问题
memdebug.c * About CLOBBER_FREED_MEMORY:** If this symbol is defined, all freed memory is overwritten with 0x7Fs.* This is useful for catching places that reference already-freed memory.** About MEMORY_CONTEXT_CHECKING:** Since we usually round request sizes up to the next power of 2, there* is often some unused space immediately after a requested data area.* Thus, if someone makes the common error of writing past what theyve* requested, the problem is likely to go unnoticed ... until the day when* there *isnt* any wasted space, perhaps because of different memory* alignment on a new platform, or some other effect. To catch this sort* of problem, the MEMORY_CONTEXT_CHECKING option stores 0x7E just beyond* the requested space whenever the request is less than the actual chunk* size, and verifies that the byte is undamaged when the chunk is freed.简单总结如下
CLOBBER_FREED_MEMORY 如果定义了这个符号所有释放的内存都会被覆盖为0x7F。这对于捕捉引用已释放内存的地方非常有用。 MEMORY_CONTEXT_CHECKING 由于我们通常将请求的大小舍入到下一个2的幂所以在请求的数据区域之后通常会有一些未使用的空间。因此如果有人犯了常见的错误超出了他们请求的范围问题可能会被忽视…直到更换平台后没有这种空间未使用空间导致内存越界使用的问题才被发现。
其实这两个宏在打开USE_ASSERT_CHECKING的使用就默认会生效。所以建议configure时记得打开enable_cassert。
/** Define this to cause pfree()d memory to be cleared immediately, to* facilitate catching bugs that refer to already-freed values.* Right now, this gets defined automatically if --enable-cassert.*/
#ifdef USE_ASSERT_CHECKING
#define CLOBBER_FREED_MEMORY
#endif/** Define this to check memory allocation errors (scribbling on more* bytes than were allocated). Right now, this gets defined* automatically if --enable-cassert or USE_VALGRIND.*/
#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
#define MEMORY_CONTEXT_CHECKING
#endif2 原理
2.1 MEMORY_CONTEXT_CHECKING
下面讲讲这两宏的原理也比较简单
正常我们申请内存都是会向上对齐到2的幂上比如申请5个字节实际上会分配8个字节出来但是你只应该使用5个字节。 但是如果你内存越界访问到第六个字节后实际上是不会发生任何破坏的因为这第六个字节也没有人会用释放时也不可能发现。这就造成了隐患这类问题都比较难差会有奇怪的逻辑报错。
如果打开MEMORY_CONTEXT_CHECKING宏后 2.2 CLOBBER_FREED_MEMORY
还有use after free的场景因为在pfree时内存块中的内容不会立即被覆盖或重写很可能发生上面已经free了但后面还能正常用的场景在某些串行逻辑下貌似一直都不会出现问题这也埋下了隐患这类问题都比较难差会有奇怪的逻辑报错。
打开CLOBBER_FREED_MEMORY后释放时会调用wipe_mem将内存覆盖成0X7F
static inline void
wipe_mem(void *ptr, size_t size)
{VALGRIND_MAKE_MEM_UNDEFINED(ptr, size);memset(ptr, 0x7F, size);VALGRIND_MAKE_MEM_NOACCESS(ptr, size);
}后面aset不会对0x7F做任何检查逻辑因为没准你的数据就全是0x7F。但是memset后肯定会将pfree的地址的数据立即覆盖掉让后面使用者能尽早发现问题看到一堆0x7F就知道是用了free后的地址了。