Apache HTTP服务器 2.0版本
APR的分配机制为发现内存问题提供了多种调试模式,本文将阐述这些模式及其使用方法。
free()
的内存的问题。其原理很简单,在用malloc
分配内存时,
以及在clear_pool
期间释放内存时,
会在这块内存的整个区域内写入FILL_BYTE
(0xa5
),
然后,校验可用内存表中的内存块是否填满了FILL_BYTE
,
并且,在palloc()
期间校验其内容仍然都是FILL_BYTE
。
如果,内存中发现有乱糟糟的URL或者不全是FILL_BYTE
,
那么,就可以肯定某个地方使用了已经释放的或者未经初始化的内存。
malloc()
,
而其后的释放将使用free()
。用于诸如Electric Fence 和 Purify的内存问题检测工具。
如果使用的是efence,则需要与ALLOC_DEBUG
选项同时使用;
而如果用的是Purify,则不要使用ALLOC_DEBUG
,
因为,本来Purify能发现的读取未经初始化的内存的错误会被ALLOC_DEBUG
所掩盖。
它会使table_{set,add,merge}n
过程检查其参数在
apr_table_t
中的位置是否安全。
目前,此选项仅在unix多进程模式下有效,但是扩展到其他平台也是可能的。
此选项需要支持__builtin_return_address()
的较新的gcc。
error_log的输出是类似这样的一个消息:
table_push: apr_table_t created by 0x804d874 hit limit of 10
用l *0x804d874
可以找到其对应的源代码。
它意味着,一个调用所分配在那个地址的apr_table_t
小于预计的初始apr_table_t
的尺寸。
这需要对alloc.c如何运作有所了解。
上述选项并不是都能同时使用的,详见下表。
ALLOC DEBUG | ALLOC USE MALLOC | POOL DEBUG | MAKE TABLE PROFILE | ALLOC STATS | |
---|---|---|---|---|---|
ALLOC DEBUG | - | No | Yes | Yes | Yes |
ALLOC USE MALLOC | No | - | No | No | No |
POOL DEBUG | Yes | No | - | Yes | Yes |
MAKE TABLE PROFILE | Yes | No | Yes | - | Yes |
ALLOC STATS | Yes | No | Yes | Yes | - |
另外,这些调试选项不适合用于多线程的服务器。 要使用这些选项进行调试,则服务器应该以单进程模式启动。
现在,这些内存调试的选项是在APR的头文件apr_general.h
中启用的。
要启用某个选项,只要去掉注解符号即可。
目前,这段(包含在 srclib/apr/include/apr_pools.h的)代码形如:
/*
#define ALLOC_DEBUG
#define POOL_DEBUG
#define ALLOC_USE_MALLOC
#define MAKE_TABLE_PROFILE
#define ALLOC_STATS
*/
typedef struct ap_pool_t {
union block_hdr *first;
union block_hdr *last;
struct cleanup *cleanups;
struct process_chain *subprocesses;
struct ap_pool_t *sub_pools;
struct ap_pool_t *sub_next;
struct ap_pool_t *sub_prev;
struct ap_pool_t *parent;
char *free_first_avail;
#ifdef ALLOC_USE_MALLOC
void *allocation_list;
#endif
#ifdef POOL_DEBUG
struct ap_pool_t *joined;
#endif
int (*apr_abort)(int retcode);
struct datastruct *prog_data;
} ap_pool_t;
要启用内存调试,只要将#define ALLOC_DEBUG
移到这段注解的上面,并重新编译服务器,即可。
要使用这些选项,在编辑头文件后,必须重新编译服务器。