Apache 2.0手册中文版翻译项目 [本文译者: kajaa + ]

项目说明 | 项目进度 | 项目讨论区 | Apache手册中文版

 


APR中内存分配的调试 - Apache HTTP服务器
<-
Apache主站 > HTTP服务器 > 文档 > 2.0版本 > Developer Documentation

APR中内存分配的调试

APR的分配机制为发现内存问题提供了多种调试模式,本文将阐述这些模式及其使用方法。

top

可用的调试选项

分配的调试 - ALLOC_DEBUG

调试支持: 定义此选项可以启用相关的代码, 以帮助发现诸如重复使用已经free()的内存的问题。

其原理很简单,在用malloc分配内存时, 以及在clear_pool期间释放内存时, 会在这块内存的整个区域内写入FILL_BYTE (0xa5), 然后,校验可用内存表中的内存块是否填满了FILL_BYTE, 并且,在palloc()期间校验其内容仍然都是FILL_BYTE。 如果,内存中发现有乱糟糟的URL或者不全是FILL_BYTE, 那么,就可以肯定某个地方使用了已经释放的或者未经初始化的内存。

Malloc的支持 - ALLOC_USE_MALLOC

如果定义了此选项,所有的内存分配将使用malloc(), 而其后的释放将使用free()

用于诸如Electric Fence 和 Purify的内存问题检测工具。 如果使用的是efence,则需要与ALLOC_DEBUG选项同时使用; 而如果用的是Purify,则不要使用ALLOC_DEBUG, 因为,本来Purify能发现的读取未经初始化的内存的错误会被ALLOC_DEBUG所掩盖。

池的调试 - POOL_DEBUG

用于检测在错误的池中指定数据为另一个池中的对象的错误。

它会使table_{set,add,merge}n过程检查其参数在 apr_table_t中的位置是否安全。 目前,此选项仅在unix多进程模式下有效,但是扩展到其他平台也是可能的。

表的调试 - MAKE_TABLE_PROFILE

提供可能太小的make_table()的诊断信息。

此选项需要支持__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_STATS

提供分配的开销的统计信息。

这需要对alloc.c如何运作有所了解。

top

允许的组合

上述选项并不是都能同时使用的,详见下表。

ALLOC DEBUG ALLOC USE MALLOC POOL DEBUG MAKE TABLE PROFILE ALLOC STATS
ALLOC DEBUG -NoYesYesYes
ALLOC USE MALLOC No-NoNoNo
POOL DEBUG YesNo-YesYes
MAKE TABLE PROFILE YesNoYes-Yes
ALLOC STATS YesNoYesYes-

另外,这些调试选项不适合用于多线程的服务器。 要使用这些选项进行调试,则服务器应该以单进程模式启动。

top

启用调试选项

现在,这些内存调试的选项是在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 移到这段注解的上面,并重新编译服务器,即可。

注意

要使用这些选项,在编辑头文件后,必须重新编译服务器。

 


项目维护者: kajaa [本文译者: kajaa + ]

项目说明 | 项目进度 | 项目讨论区 | Apache手册中文版