0
点赞
收藏
分享

微信扫一扫

VxWorks内存泄漏检查【转】

孟佳 2022-05-06 阅读 114

#VxWorks内存泄漏检查【转】
来源:https://borkhuis.home.xs4all.nl/vxworks/vxw_pt6.html#6.2

 //在运行测试程序前运行
 ld <findMalloc.o
 find_malloc
 ld <memTrack.o
 

以下为findMalloc.c代码

/*
 * Memory diagnosics: find_malloc.c
 *
 * Author: Richard Dickson (dickson@jlab.org)
 *
 * $Id: findMalloc.c,v 1.1 1999/11/29 23:27:48 borkhuis Exp $
 *
 */

#include <symLib.h>

char *addr_of_malloc = NULL;
char *addr_of_calloc = NULL;
char *addr_of_free = NULL;

extern SYMTAB_ID sysSymTbl;

int find_malloc(void)
{
 SYM_TYPE type;
 STATUS   status;

 status  = symFindByName(sysSymTbl,
                         "_malloc",
                         &addr_of_malloc,
                         &type);

 status |= symFindByName(sysSymTbl,
                         "_calloc",
                         &addr_of_calloc,
                         &type);

 status |= symFindByName(sysSymTbl,
                         "_free",
                         &addr_of_free,
                         &type);

 return status;
}

以下为memCheck.c代码

/*
 * Memory diagnosics: memTrack.c
 *
 * Author: Richard Dickson (dickson@jlab.org)
 *
 * $Id: memTrack.c,v 1.1 1999/11/29 23:27:48 borkhuis Exp $
 *
 */

/* Richard Dickson  July, 1998 */
/* Routines to report per task memory allocation */

#include <stdio.h>
#include <stdlib.h>
#include <taskLib.h>
#include <symLib.h>

/* these three must have been initialized by the routine find_malloc before this module is loaded */
extern void *(*addr_of_malloc)(size_t size);
extern void *(*addr_of_calloc)(size_t nelem, size_t size);
extern void  (*addr_of_free)(void *ptr);

extern SYMTAB_ID sysSymTbl;

/****************************************************************************/
long getStackPointer(void)
{				/* assembly routine to return stack pointer value */
 static const short code_array[] = {
	  	                    0x4e56, 0000,	/* LINK.W  A6,#0 */
			            0x200F,		/* MOVE.L  A7,D0 */
			            0x4e5e,		/* ULNK    A6    */
			            0x4e75		/* RTS		 */
                                   };

 return (((long(*)()) code_array)());
}

/****************************************************************************/
void *malloc(size_t size)
{
 WIND_TCB *tcb;					/* pointer to task control block */
 void *ret_val;

 ret_val = (*addr_of_malloc)(size+4);		/* call real malloc, ask for 4 extra bytes to store TID */

 if (ret_val)
  {						/* if malloc success */
   long *sp;					/* stack pointer */

   tcb = (WIND_TCB*)taskIdSelf();		/* get TID */
   *(WIND_TCB**)ret_val = tcb;			/* put TID at start of malloc buffer */
   tcb->spare1++;				/* inc allocated block counter for this task */
   tcb->spare2 += (*((int*)ret_val - 1) - 12);	/* vxWorks puts length of buff (+ buf's linked list overhead
                                                   size (8 bytes)) into longword before malloc's return address.
                                                   Subtract 4 more for the extra 4 asked for (total 12) to find
                                                   size of caller's request.  Add this to this tasks total bytes
                                                   allocated */
   sp = (long*)getStackPointer();		/* get stack pointer so the caller of this routine can be found */
   tcb->spare3 = (int)sp[7] - 6;		/* caller PC (JSR instruction is 6 bytes long itself) */
  }

 (char*)ret_val += 4;				/* adjust malloc return value so caller doesn't see TID info */
 return ret_val; 
}

/****************************************************************************/
void *calloc(size_t nelem, size_t size)
{
 WIND_TCB *tcb;					/* pointer to task control block */
 void *ret_val;
 unsigned bytes;

 bytes = nelem*size;				/* bytes to calloc */
 ret_val = (*addr_of_calloc)(bytes+4, 1);	/* call real calloc, ask for 4 extra bytes to store TID */

 if (ret_val)
  {                                             /* if calloc success */
   long *sp;					/* stack pointer */
   tcb = (WIND_TCB*)taskIdSelf();               /* get TID */
   *(WIND_TCB**)ret_val = tcb;                  /* put TID at start of calloc buffer */
   tcb->spare1++;                               /* inc allocated block counter for this task */
   tcb->spare2 += (*((int*)ret_val - 1) - 12);  /* vxWorks puts length of buff (+ buf's linked list overhead
                                                   size (8 bytes)) into longword before calloc's return address.
                                                   Subtract 4 more for the extra 4 asked for (total 12) to find
                                                   size of caller's request.  Add this to this tasks total bytes
                                                   allocated */
   sp = (long*)getStackPointer();               /* get stack pointer so the caller of this routine can be found */
   tcb->spare3 = (int)sp[7] - 6;		/* caller PC (JSR instruction is 6 bytes long itself) */
  }

 (char*)ret_val += 4;                           /* adjust calloc return value so caller doesn't see TID info */
 return ret_val; 
}

/****************************************************************************/
void free(void *ptr)
{
 WIND_TCB *tcb;                                 /* pointer to task control block */

 (char*)ptr -= 4;				/* adjust pointer for 4 extra bytes asked for by malloc or calloc */
 tcb = *(WIND_TCB**)ptr;			/* get TID of task that did malloc or calloc */
 if (!((unsigned)tcb & 0x80000000) && taskIdVerify((int)tcb) == OK)
  {						/* if not already freed and TID is real */
   *(unsigned*)ptr |= 0x80000000;		/* set top bit in TID to indicate not allocated */
   tcb->spare1--;				/* adjust task's allocated block counter */
   tcb->spare2 -= (*((int*)ptr - 1) - 12);	/* adjust task's allocated byte counter */
  }

 (*addr_of_free)(ptr);				/* call real free routine */

 return; 
}

/****************************************************************************/
#define MAX_TASKS 256

int memTrack(void)
{
 int tid[MAX_TASKS];
 int i, num_tasks;
 int blocks = 0;
 int bytes  = 0;
 char caller[64];
 int actual_addr;
 SYM_TYPE sym_type;

 num_tasks = taskIdListGet(tid, MAX_TASKS);		/* get all TIDs */

 printf("\n");
 printf("Task Name            TID  Blocks    Bytes                    Last-caller       PC\n");
 printf("--------------- -------- ------- -------- ------------------------------ --------\n");
 for (i=0; i<num_tasks; i++)
  {
   if (((WIND_TCB*)tid[i])->spare1)
    {						/* if blocks allocated by this task */
     blocks += ((WIND_TCB*)tid[i])->spare1;	/* add up for total */
     bytes  += ((WIND_TCB*)tid[i])->spare2;	/* add up for total */
     symFindByValue(sysSymTbl,			/* find caller routine name */
                    ((WIND_TCB*)tid[i])->spare3,
                    caller,
                    &actual_addr,
                    &sym_type); 

     sprintf(caller, "%s + 0x%x", caller, ((WIND_TCB*)tid[i])->spare3 - actual_addr);
     printf("%-15s %8x %7d %8d %30s %8x\n", taskName(tid[i]), tid[i],
                                            ((WIND_TCB*)tid[i])->spare1,
                                            ((WIND_TCB*)tid[i])->spare2,
                                            caller, 
                                            ((WIND_TCB*)tid[i])->spare3);
    }
  }
 printf("TOTAL                  %9d %8d\n", blocks, bytes);

 return 0;
}


举报

相关推荐

0 条评论