设为首页 收藏本站
查看: 966|回复: 0

[经验分享] keepalived源码浅析——Memory 内存管理

[复制链接]

尚未签到

发表于 2015-11-19 15:08:16 | 显示全部楼层 |阅读模式
  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 &quot;memory.h&quot;
#include &quot;utils.h&quot;
/* 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(&quot;zalloc[%3d:%3d], %p, %4ld at %s, %3d, %s\n&quot;,
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(&quot;free NULL in %s, %3d, %s\n&quot;, 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(&quot;free corrupt, buffer overrun [%3d:%3d], %p, %4ld at %s, %3d, %s\n&quot;,
i, number_alloc_list,
buf, alloc_list.size, file,
line, function);
dump_buffer(alloc_list.ptr,
alloc_list.size + sizeof (long));
printf(&quot;Check_sum\n&quot;);
dump_buffer((char *) &alloc_list.csum,
sizeof(long));
debug |= 512;/* Memory Error detect */
}
}
break;
}
i++;
}
/*  Not found */
if (i == number_alloc_list) {
printf(&quot;Free ERROR %p\n&quot;, 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(&quot;free  [%3d:%3d], %p, %4ld at %s, %3d, %s\n&quot;,
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(&quot;\n---[ Keepalived memory dump for (%s)]---\n\n&quot;, banner);
while (i < number_alloc_list) {
switch (alloc_list.type) {
case 3:
badptr++;
printf
(&quot;null pointer to realloc(nil,%ld)! at %s, %3d, %s\n&quot;,
alloc_list.size, alloc_list.file,
alloc_list.line, alloc_list.func);
break;
case 4:
badptr++;
printf
(&quot;pointer not found in table to free(%p) [%3d:%3d], at %s, %3d, %s\n&quot;,
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
(&quot;  -> pointer allready released at [%3d:%3d], at %s, %3d, %s\n&quot;,
(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(&quot;null pointer to free(nil)! at %s, %3d, %s\n&quot;,
alloc_list.file, alloc_list.line,
alloc_list.func);
break;
case 1:
overrun++;
printf(&quot;%p [%3d:%3d], %4ld buffer overrun!:\n&quot;,
alloc_list.ptr, i, number_alloc_list,
alloc_list.size);
printf(&quot; --> source of malloc: %s, %3d, %s\n&quot;,
alloc_list.file, alloc_list.line,
alloc_list.func);
break;
case 9:
sum += alloc_list.size;
printf(&quot;%p [%3d:%3d], %4ld not released!:\n&quot;,
alloc_list.ptr, i, number_alloc_list,
alloc_list.size);
printf(&quot; --> source of malloc: %s, %3d, %s\n&quot;,
alloc_list.file, alloc_list.line,
alloc_list.func);
break;
}
i++;
}
printf(&quot;\n\n---[ Keepalived memory dump summary for (%s) ]---\n&quot;, banner);
printf(&quot;Total number of bytes not freed...: %d\n&quot;, sum);
printf(&quot;Number of entries not freed.......: %d\n&quot;, n);
printf(&quot;Maximum allocated entries.........: %d\n&quot;, number_alloc_list);
printf(&quot;Number of bad entries.............: %d\n&quot;, badptr);
printf(&quot;Number of buffer overrun..........: %d\n\n&quot;, overrun);
if (sum || n || badptr || overrun)
printf(&quot;=> Program seems to have some memory problem !!!\n\n&quot;);
else
printf(&quot;=> Program seems to be memory allocation safe...\n\n&quot;);
}
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(&quot;realloc %p %s, %3d %s\n&quot;, 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(&quot;realloc ERROR no matching zalloc %p \n&quot;, 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(&quot;realloc [%3d:%3d] %p, %4ld %s %d %s -> %p %4ld %s %d %s\n&quot;,
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(&quot;Parent process&quot;);
#endif

  

check_daemon.c中的stop_check函数

#ifdef _DEBUG_
keepalived_free_final(&quot;Healthcheck child process&quot;);
#endif


  


  vrrp_daemon.c中的stop_vrrp函数

#ifdef _DEBUG_
keepalived_free_final(&quot;VRRP Child process&quot;);
#endif

  




  
  



版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-141250-1-1.html 上篇帖子: keepalived源码浅析——Global_data全局数据解析 下篇帖子: HAproxy+keepalived+mysql高可用性Linux系统集群
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表