MALLOC_CHECK_=0, 和没设置一样,将忽略这些错误
MALLOC_CHECK_=1, 将打印一个错误告警
MALLOC_CHECK_=2, 程序将收到SIGABRT信号退出
GNU C Library 可以根据环境变量MALLOC_CHECK_来决定是否在运行时可检测程序中的内存问题。而内存问题有时候表现得非常古怪,比如random crash, crash的点又经常变,甚至coredump中也没什么栈信息。这时候可以用这个方法来验证一下。知识还没办法打印出错点对应的地址,有些遗憾。
下面是一个内存越界的例子:
#include
#include
#include
#define BUF_SIZE 32
int main()
{
int i;
char * buf1 = (char*) malloc(BUF_SIZE);
printf("buf1: [%x] %p\n", buf1, buf1);
memset(buf1, 'c', BUF_SIZE + 10);
printf("%s:%d buf1: [%x]\n", __func__, __LINE__, buf1);
free(buf1);
char * buf = (char*) malloc(BUF_SIZE);
printf("buf: [%x] %p\n", buf, buf);
for (i = 0; i < BUF_SIZE; i++)
{
printf("%2x ", (0xFF & buf[i]));
}
free(buf);
printf("\n");
return 0;
}
运行结果:
$ g++ test.cpp -o test
malloc: using debugging hooks
malloc: using debugging hooks
malloc: using debugging hooks
malloc: using debugging hooks
malloc: using debugging hooks
malloc: using debugging hooks
$ ./test
malloc: using debugging hooks
buf1: [9b7f050]
free(): invalid pointer 0x9b7f050!
malloc: top chunk is corrupt
buf: [9ba0008]
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
$ export MALLOC_CHECK_=2
$ ./test
buf1: [a01d050]
Aborted
$ export MALLOC_CHECK_=0
$ ./test
buf1: [9e12050]
buf: [9e33008]
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
$ unset MALLOC_CHECK_
$ ./test
buf1: [9062050]
buf: [9062050]
0 0 0 0 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
[root@localhost malloc_check]# export MALLOC_CHECK_=1
[root@localhost malloc_check]# ./a.out
buf1: [216b010] 0x216b010
main:21 buf1: [216b010]
*** Error in `./a.out': free(): invalid pointer: 0x000000000216b010 ***
*** Error in `./a.out': malloc: top chunk is corrupt: 0x000000000216b030 ***
buf: [218c010] 0x218c010
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[root@localhost malloc_check]#
通过比较两次分配的指针地址可以看出,当使用MALLOC_CHECK_时,如果检测到memory corrupt时,有问题的memory将被特殊处理,而不是像正常情况一样被分配给新的request. 因此有可能出现使用了此环境变量之后,原本可能发生crash的程序反而工作正常了。
对于double free, 会给出类似下面的输出:
free(): invalid pointer 0x9186050!
遗憾的是此方法没能检测到读越界。
附info malloc 中对此环境变量的说明:
Recent versions of Linux libc (later than 5.4.23) and GNU libc (2.x)
include a malloc implementation which is tunable via environment vari-
ables. When MALLOC_CHECK_ is set, a special (less efficient) implemen-
tation is used which is designed to be tolerant against simple errors,
such as double calls of free() with the same argument, or overruns of a
single byte (off-by-one bugs). Not all such errors can be protected
against, however, and memory leaks can result. If MALLOC_CHECK_ is set
to 0, any detected heap corruption is silently ignored; if set to 1, a
diagnostic is printed on stderr; if set to 2, abort() is called immedi-
ately. This can be useful because otherwise a crash may happen much
later, and the true cause for the problem is then very hard to track