|
Memory模块的作用:封装了内存申请和释放函数,打印文件、函数、申请内存大小、代码行数等信息,dubug模式下定位内存泄露位置。
Memory.h源码:
#ifndef _MEMORY_H
#define _MEMORY_H
/* system includes */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* extern types */
extern unsigned long mem_allocated;
extern void *xalloc(unsigned long size);
extern void *zalloc(unsigned long size);
extern void xfree(void *p);
/* Global alloc macro */
#define ALLOC(n) (xalloc(n))
/* Local defines */
#ifdef _DEBUG_
#define MAX_ALLOC_LIST 2048
#define MALLOC(n) ( keepalived_malloc((n), \
(__FILE__), (char *)(__FUNCTION__), (__LINE__)) )
#define FREE(b) ( keepalived_free((b), \
(__FILE__), (char *)(__FUNCTION__), (__LINE__)) )
#define REALLOC(b,n) ( keepalived_realloc((b), (n), \
(__FILE__), (char *)(__FUNCTION__), (__LINE__)) )
/* Memory debug prototypes defs */
extern char *keepalived_malloc(unsigned long, char *, char *, int);
extern int keepalived_free(void *, char *, char *, int);
extern void *keepalived_realloc(void *, unsigned long, char *, char *, int);
extern void keepalived_free_final(char *);
#else
#define MALLOC(n) (zalloc(n))
#define FREE(p) (xfree(p))
#define REALLOC(p,n) (realloc((p),(n)))
#endif
/* Common defines */
#define FREE_PTR(P) if((P)) FREE((P));
#endif
Memory.c源码:
#include "memory.h"
#include "utils.h"
/* Global var */
unsigned long mem_allocated;/* Total memory used in Bytes */
void *
xalloc(unsigned long size)
{
void *mem;
if ((mem = malloc(size)))
mem_allocated += size;
return mem;
}
void *
zalloc(unsigned long size)
{
void *mem;
if ((mem = malloc(size))) {
memset(mem, 0, size);
mem_allocated += size;
}
return mem;
}
void
xfree(void *p)
{
mem_allocated -= sizeof (p);
free(p);
p = NULL;
}
/* KeepAlived memory management. in debug mode,
* help finding eventual memory leak.
* Allocation memory types manipulated are : //内存泄露类型
*
* +type+--------meaning--------+
* ! 0 ! Free slot !
* ! 1 ! Overrun !
* ! 2 ! free null !
* ! 3 ! realloc null !
* ! 4 ! Not previus allocated !
* ! 8 ! Last free list !
* ! 9 ! Allocated !
* +----+-----------------------+
*
* global variabel debug bit 9 ( 512 ) used to
* flag some memory error.
*
*/
#ifdef _DEBUG_
typedef struct {
int type;
int line;
char *func;
char *file;
void *ptr;
unsigned long size;
long csum;
} MEMCHECK;
/* Last free pointers */
static MEMCHECK free_list[256];
static MEMCHECK alloc_list[MAX_ALLOC_LIST]; //结构体数组
static int number_alloc_list = 0;
static int n = 0;/* Alloc list pointer */
static int f = 0;/* Free list pointer */
char *
keepalived_malloc(unsigned long size, char *file, char *function, int line) //内存申请
{
void *buf;
int i = 0;
long check;
buf = zalloc(size + sizeof (long));
check = 0xa5a5 + size;
*(long *) ((char *) buf + size) = check;
while (i < number_alloc_list) {
if (alloc_list.type == 0)
break;
i++;
}
if (i == number_alloc_list)
number_alloc_list++;
assert(number_alloc_list < MAX_ALLOC_LIST);
alloc_list.ptr = buf;
alloc_list.size = size;
alloc_list.file = file;
alloc_list.func = function;
alloc_list.line = line;
alloc_list.csum = check;
alloc_list.type = 9;
if (debug & 1)
printf("zalloc[%3d:%3d], %p, %4ld at %s, %3d, %s\n",
i, number_alloc_list, buf, size, file, line,
function);
n++;
return buf;
}
int
keepalived_free(void *buffer, char *file, char *function, int line) //内存释放
{
int i = 0;
void *buf;
/* If nullpointer remember */
if (buffer == NULL) {
i = number_alloc_list++;
assert(number_alloc_list < MAX_ALLOC_LIST);
alloc_list.ptr = buffer;
alloc_list.size = 0;
alloc_list.file = file;
alloc_list.func = function;
alloc_list.line = line;
alloc_list.type = 2;
if (debug & 1)
printf("free NULL in %s, %3d, %s\n", file,
line, function);
debug |= 512;/* Memory Error detect */
return n;
} else
buf = buffer;
while (i < number_alloc_list) {
if (alloc_list.type == 9 && alloc_list.ptr == buf) {
if (*
((long *) ((char *) alloc_list.ptr +
alloc_list.size)) ==
alloc_list.csum)
alloc_list.type = 0;/* Release */
else {
alloc_list.type = 1;/* Overrun */
if (debug & 1) {
printf("free corrupt, buffer overrun [%3d:%3d], %p, %4ld at %s, %3d, %s\n",
i, number_alloc_list,
buf, alloc_list.size, file,
line, function);
dump_buffer(alloc_list.ptr,
alloc_list.size + sizeof (long));
printf("Check_sum\n");
dump_buffer((char *) &alloc_list.csum,
sizeof(long));
debug |= 512;/* Memory Error detect */
}
}
break;
}
i++;
}
/* Not found */
if (i == number_alloc_list) {
printf("Free ERROR %p\n", buffer);
number_alloc_list++;
assert(number_alloc_list < MAX_ALLOC_LIST);
alloc_list.ptr = buf;
alloc_list.size = 0;
alloc_list.file = file;
alloc_list.func = function;
alloc_list.line = line;
alloc_list.type = 4;
debug |= 512;
return n;
}
if (buffer != NULL)
xfree(buffer);
if (debug & 1)
printf("free [%3d:%3d], %p, %4ld at %s, %3d, %s\n",
i, number_alloc_list, buf,
alloc_list.size, file, line, function);
free_list[f].file = file;
free_list[f].line = line;
free_list[f].func = function;
free_list[f].ptr = buffer;
free_list[f].type = 8;
free_list[f].csum = i;/* Using this field for row id */
f++;
f &= 255;
n--;
return n;
}
void
keepalived_free_final(char *banner) //定位内存泄露位置
{
unsigned int sum = 0, overrun = 0, badptr = 0;
int i, j;
i = 0;
printf("\n---[ Keepalived memory dump for (%s)]---\n\n", banner);
while (i < number_alloc_list) {
switch (alloc_list.type) {
case 3:
badptr++;
printf
("null pointer to realloc(nil,%ld)! at %s, %3d, %s\n",
alloc_list.size, alloc_list.file,
alloc_list.line, alloc_list.func);
break;
case 4:
badptr++;
printf
("pointer not found in table to free(%p) [%3d:%3d], at %s, %3d, %s\n",
alloc_list.ptr, i, number_alloc_list,
alloc_list.file, alloc_list.line,
alloc_list.func);
for (j = 0; j < 256; j++)
if (free_list[j].ptr == alloc_list.ptr)
if (free_list[j].type == 8)
printf
(" -> pointer allready released at [%3d:%3d], at %s, %3d, %s\n",
(int) free_list[j].csum,
number_alloc_list,
free_list[j].file,
free_list[j].line,
free_list[j].func);
break;
case 2:
badptr++;
printf("null pointer to free(nil)! at %s, %3d, %s\n",
alloc_list.file, alloc_list.line,
alloc_list.func);
break;
case 1:
overrun++;
printf("%p [%3d:%3d], %4ld buffer overrun!:\n",
alloc_list.ptr, i, number_alloc_list,
alloc_list.size);
printf(" --> source of malloc: %s, %3d, %s\n",
alloc_list.file, alloc_list.line,
alloc_list.func);
break;
case 9:
sum += alloc_list.size;
printf("%p [%3d:%3d], %4ld not released!:\n",
alloc_list.ptr, i, number_alloc_list,
alloc_list.size);
printf(" --> source of malloc: %s, %3d, %s\n",
alloc_list.file, alloc_list.line,
alloc_list.func);
break;
}
i++;
}
printf("\n\n---[ Keepalived memory dump summary for (%s) ]---\n", banner);
printf("Total number of bytes not freed...: %d\n", sum);
printf("Number of entries not freed.......: %d\n", n);
printf("Maximum allocated entries.........: %d\n", number_alloc_list);
printf("Number of bad entries.............: %d\n", badptr);
printf("Number of buffer overrun..........: %d\n\n", overrun);
if (sum || n || badptr || overrun)
printf("=> Program seems to have some memory problem !!!\n\n");
else
printf("=> Program seems to be memory allocation safe...\n\n");
}
void *
keepalived_realloc(void *buffer, unsigned long size, char *file, char *function,
int line)
{
int i = 0;
void *buf, *buf2;
long check;
if (buffer == NULL) {
printf("realloc %p %s, %3d %s\n", buffer, file, line, function);
i = number_alloc_list++;
assert(number_alloc_list < MAX_ALLOC_LIST);
alloc_list.ptr = NULL;
alloc_list.size = 0;
alloc_list.file = file;
alloc_list.func = function;
alloc_list.line = line;
alloc_list.type = 3;
return keepalived_malloc(size, file, function, line);
}
buf = buffer;
while (i < number_alloc_list) {
if (alloc_list.ptr == buf) {
buf = alloc_list.ptr;
break;
}
i++;
}
/* not found */
if (i == number_alloc_list) {
printf("realloc ERROR no matching zalloc %p \n", buffer);
number_alloc_list++;
assert(number_alloc_list < MAX_ALLOC_LIST);
alloc_list.ptr = buf;
alloc_list.size = 0;
alloc_list.file = file;
alloc_list.func = function;
alloc_list.line = line;
alloc_list.type = 9;
debug |= 512;/* Memory Error detect */
return NULL;
}
buf2 = ((char *) buf) + alloc_list.size;
if (*(long *) (buf2) != alloc_list.csum) {
alloc_list.type = 1;
debug |= 512;/* Memory Error detect */
}
buf = realloc(buffer, size + sizeof (long));
check = 0xa5a5 + size;
*(long *) ((char *) buf + size) = check;
alloc_list.csum = check;
if (debug & 1)
printf("realloc [%3d:%3d] %p, %4ld %s %d %s -> %p %4ld %s %d %s\n",
i, number_alloc_list, alloc_list.ptr,
alloc_list.size, file, line, function, buf, size,
alloc_list.file, alloc_list.line,
alloc_list.func);
alloc_list.ptr = buf;
alloc_list.size = size;
alloc_list.file = file;
alloc_list.line = line;
alloc_list.func = function;
return buf;
}
#endif
调用位置
main.c中的stop_keepalived函数
#ifdef _DEBUG_
keepalived_free_final("Parent process");
#endif
check_daemon.c中的stop_check函数
#ifdef _DEBUG_
keepalived_free_final("Healthcheck child process");
#endif
vrrp_daemon.c中的stop_vrrp函数
#ifdef _DEBUG_
keepalived_free_final("VRRP Child process");
#endif
版权声明:本文为博主原创文章,未经博主允许不得转载。 |
|