⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rmalloc.c.svn-base

📁 sigmadesign smp8623 gui source code ,bingo
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* =====================================================================   File:	rmalloc.c   Author:	Rammi   Date:	11/16/1995 (started)   Reminder:	Use at your own risk.   Content:	Debug wrapper functions for the malloc library.   		For more information see rmalloc.h   Last Change: $Date: 2006/01/29 18:56:12 $   History:     $Log: rmalloc.c,v $   History:     Revision 1.9  2006/01/29 18:56:12  rammi   History:     Streamlined various things due to a proposal by Brant L Gurganus. Thanks Brant!   History:   History:     Revision 1.8  2003/01/31 15:47:52  rammi   History:     Changed signature of Rmalloc_set_flags() and Rmalloc_retag to return pointer.   History:   History:     Revision 1.7  2003/01/31 15:04:20  rammi   History:     Fixed unclosed comment.   History:   History:     Revision 1.6  2003/01/31 14:51:48  rammi   History:     Updated version to 1.16   History:   History:     Revision 1.5  2003/01/31 14:49:00  rammi   History:     Unset RM_STATIC flag in realloc to avoid warning on free   History:   History:     Revision 1.4  2002/04/22 17:39:34  rammi   History:     Added output of BREAK_GENERATION environment variable when used   History:   History:     Revision 1.3  2002/04/22 16:28:06  rammi   History:     Finetuning of generations feature   History:   History:     Revision 1.2  2002/04/22 15:26:16  rammi   History:     Added Karl Brace's generations feature.   History:   Pre-CVS history:   		04/11/1996 (Rammi)		Changed to hashed table for faster access   		04/15/1996 (Rammi)		Included statistics		08/16/1997 (Rammi)		Automatic output of used memory on exit		08/25/1997 (Rammi)		Catching signals in critical situations (partly)		02/18/1998 (Rammi)		Testing memory before outputting statistic		Overworked signal handling in IsPossibleFilePos()		Made it unnecessary of changing all mallocs etc		to upper case		02/19/1998 (Rammi)		Little changes to compile on Alpha (64bit) without		warnings		03/10/1998 (Rammi)		Added comments.		03/24/1998 (Rammi)		Allowed compilation without WITH_FLAGS		04/07/1998 (Rammi)		All output goes to stderr..		1.11beta is released as 1.11!		05/28/1998 (Rammi)		Changed comments to english for public release		Added some more signal handling.		06/01/1998 (Rammi)		Added output of (flagged) strings in ELOQUENT mode.		Changed all names from my_... to R...		This is version 1.12!		11/13/1998 (Rammi)		Multiple defined label when using ELOQUENT mode now fixed.		Added getcwd wrapper as a prototype how to handle library		functions returning heap memory.		This is version 1.13!	        06/10/99 (Rammi)		The getcwd wrapper had a bug as Greg Silverman pointed		out (I should better have tested it!). Also fixed a		missing prototype and improved the signal handling in		rtest to allow receiving more signals while handling		one.   ===================================================================== *//* =========   INCLUDEs:   ========= */#define ALLOW_OS_CODE 1#include <stdio.h>#include <unistd.h>#include <string.h>#include <strings.h>#include <assert.h>#include <setjmp.h>#include <signal.h>#undef  MALLOC_DEBUG		/* here we need the correct malloc functions */#define RM_NEED_PROTOTYPES	/* but we want to compare prototypes */#include "rmalloc.h"/* ========   DEFINEs:   ======== *//* Actual version */#define VERSION         "1.17"/* ================================================================== *//* ============ Switch settings for different behaviours ============ *//* ============        Please set as needed              ============ *//* ================================================================== *//* This switch sets, how and when the allocated blocks are tested * on correctness. Each block is tested at least when * reallocating/freeing it. * Possible values: * 	0:		Minimum testing. Uses less memory, but *	                does not allow statistics. * 	1:		Extra testing possible by using RM_TEST *	                macro. Statistics possible. *   	2:		Testing ALL blocks on every malloc/free. *	                Statistics possible. */#ifndef RM_TEST_DEPTH#define RM_TEST_DEPTH 	1#endif/* This switch sets whether Karl's generations feature should be used * See the HTML doc for a indepth explanation of generations. * If set generations are used, otherwise no generations are included. */#define GENERATIONS#ifdef GENERATIONS/* BREAK_GENERATION_COND is the condition to find the generation  you are * interested in. * Set your debugger to the function rmalloc_generation() to find out which * function stack creates that generation. * You can either set it as a comparision directly to the number of a * generation (known from a previous run), a comparision to the function * GetBreakGenerationEnv() which reads the break generation from the environment * variable BREAK_GENERATION or don't set it so the break feature is not used. * The macro form allows for more complicated conditions, see example below. */#define BREAK_GENERATION_COND(nr) ((nr) == GetBreakGenerationEnv())/* #define BREAK_GENERATION_COND(nr) ((nr) == 125) *//* #define BREAK_GENERATION_COND(nr) ((nr) == 42  ||  (nr) == 4711) *//* The maximum number of generations you'd like to see in the statistics */#define MAX_STAT_GENERATIONS 3#endif /* GENERATIONS *//* Switch on EXTENTED alloc information. (Makes sense if an actual * error is observed such as a multiple free) *///#define ELOQUENT/* Allows setting of special flags with the RM_SET_FLAGS macro. * Needs more memory. */#define WITH_FLAGS/* Allows realloc(NULL, ...) * Posix allows this but there are some old malloc libraries * which crash on this. Switch on if you want to be compatible. *//* #define ALLOW_REALLOC_NULL *//* Allows free(NULL) * I still consider this an error in my progs because I use * NULL always as a very special value. *//* #define ALLOW_FREE_NULL *//* ================================================================== *//* ========================  Other Defines  ========================= *//* ================================================================== *//* Alignment (8 bytes are ok for virtually all machines) */#define ALIGNMENT	8/* Output message header: */#define HEAD		"<MALLOC_DEBUG>\t"/* Alignment padding: */#define ALIGN(s)	(((s+ALIGNMENT-1)/ALIGNMENT)*ALIGNMENT)/* Magic marker for block start: */#define PREV_STOP 	0x55555555/* Additional space for block begin to keep alignment: */#define START_SPACE     ALIGN(sizeof(begin))/* Additional space at end of block */#define END_SPACE       (sizeof(End))/* Overall additional space per block: */#define EXTRA_SPACE     (START_SPACE+END_SPACE)/* Hashtable size: */#define HASHSIZE	513/* Hash function: */#define HASH(p)		((((unsigned long)(p))/ALIGNMENT)%HASHSIZE)/* ==========================   STRUCTs, TYPEDEFs & ENUMs:   ========================== *//* This Information is added to the beginning of every * allocated block. */typedef struct _begin {  unsigned       StpA;		/* Magic bytes */#if RM_TEST_DEPTH > 0  struct _begin	*Next,		/* for linking in forward */	        *Prev;		/* and backward direction */#endif  const char	*File;		/* Filepos of allocation command */  size_t	 Size;		/* Size demanded */#ifdef GENERATIONS  unsigned       Generation;    /* All mallocs are numbered */#endif#ifdef WITH_FLAGS  unsigned       Flags;		/* Special flags */#endif  unsigned 	 StpB;		/* Magic bytes */} begin;/* * Global data. */typedef struct _global {  unsigned	 isInitialized;	/* Flag: already initialized? */  unsigned	 BlockCount;    /* Number of allocated blocks */} global;/* =======   CONSTs:   ======= *//* Magic block end: */static unsigned char End[] = {  0xA5, 0xA5, 0xA5, 0xA5,	/* odd */  0x5B, 0x5B, 0x5B, 0x5B,	/* odd */  0xAB, 0xAB, 0xAB, 0xAB,	/* odd */  0xAA, 0x55, 0xAA, 0x55	/* odd */};/* ========   GLOBALs:   ======== */#ifdef GENERATIONS/* The current generation. This is simply incremented which each call. */static unsigned cur_generation = 0;#endif/* =======   LOCALs:   ======= */#if RM_TEST_DEPTH > 0/* Stop marker for linked list of allocated blocks: */static begin ChainTempl = {  PREV_STOP,  &ChainTempl,  &ChainTempl,  "<Special>",  0,#ifdef GENERATIONS  0,#endif#ifdef WITH_FLAGS  0,#endif  PREV_STOP};/* Hashed linked lists: */static begin Chain[HASHSIZE];/* Global data used: */static global Global = {  0,				/* is initialized?  */  0				/* number of blocks */};#endif /* RM_TEST_DEPTH *//* Internally used longjmp target used if errors occure. */static jmp_buf   errorbuf;/* ========   FORWARD:   ======== */static int       FindBlk(const unsigned char *P);/* ===============================================================   			IMPLEMENTATION   =============================================================== *//* =============================================================================   Function:		FatalSignal	// local //   Author:		Rammi   Date:		08/25/1997   Return:		---   Parameter:		signum    signal number   Purpose:		Signal handler f�r fatal signals (SIGBUS, SIGSEGV)   ============================================================================= *///static void FatalSignal(int signum)//{//  /* --- jump to a save place --- *///  longjmp(errorbuf, signum);//}/* =============================================================================   Function:		IsPossibleFilePos	// local //   Author:		Rammi   Date:		11/30/1996   Return:		!= 0    possibly ok                        0       seems not so   Parameter:		file	possible filename			size    possible size   Purpose:		Decide whether file could be a filename and   			size a block size.   ============================================================================= */static int IsPossibleFilePos(const char *file, int size){  void   (*old_sigsegv_handler)(int) = SIG_DFL;  void   (*old_sigbus_handler)(int)  = SIG_DFL;//  char    *dp;//  int      ret;  if (setjmp(errorbuf)) {    /* uh oh, we got a kick in the ass */    signal(SIGSEGV, old_sigsegv_handler);    signal(SIGBUS,  old_sigbus_handler);    printf ("hola\n");    return 0;  }  printf ("nohola\n");//  /* --- the following is dangerous! So catch signals --- *///  old_sigsegv_handler = signal(SIGSEGV, FatalSignal);//  old_sigbus_handler  = signal(SIGBUS,  FatalSignal);////  dp  = strchr(file, ':');	/* file pos needs : */////  ret =  (dp   &&   dp-file > 3   &&   !strncmp(dp-2, ".c", 2)   &&//	  atoi(dp+1) > 0   &&   size >= 0);////  /* --- danger is over! --- *///  signal(SIGSEGV, old_sigsegv_handler);//  signal(SIGBUS,  old_sigbus_handler);////  return ret;  return 0;}#ifdef GENERATIONS/* =============================================================================   Function:		GetBreakGenerationEnv	// lokal //   Author:		Rammi   Date:		04/22/2002   Return:	        the content of the BREAK_GENERATION environment variable                        or 0   Parameter:		---   Purpose:		Return the content of the environment variable                        BREAK_GENERATION (a number indicating which is the                        generation you want to break with the debugger).   ============================================================================= */static unsigned GetBreakGenerationEnv(void){  /* The environment variable is buffered here for faster access. */  static char *breakGenerationEnv = (char *)-1;  /** The result of the conversion to unsigned is buffered here. */  static unsigned result = 0;  if (breakGenerationEnv == (char *)-1) {    /* 1st call: get the environment variable */    breakGenerationEnv = getenv("BREAK_GENERATION");    if (breakGenerationEnv != NULL) {      /* try conversion */      result = atoi(breakGenerationEnv);      fprintf(stderr,	      HEAD "Using environment variable BREAK_GENERATION=%d\n",	      result);    }  }  return result;}#endif /* GENERATIONS *//* =============================================================================   Function:		ControlBlock	// lokal //   Author:		Rammi   Date:		11/16/1995   Return:		---   Parameter:		Bkl	Pos of allocated block (original)   			file	file pos from where initial lib function				was called   Purpose:		Control integrity of block   ============================================================================= */static void ControlBlock(begin *B, const char *file){  unsigned char *p = (((unsigned char *)B)+START_SPACE);#if RM_TEST_DEPTH > 0  int DoAbort = 0;#endif  /* === the very beginning === */  if (B->StpA != PREV_STOP) {#if RM_TEST_DEPTH > 0    DoAbort = 1;#endif    fprintf(stderr, HEAD	    "Corrupted block begin (overwritten from elsewhere)\n"	    "\tshould be: %08x\n"	    "\tis:        %08x\n"#ifdef GENERATIONS	    "\tblock was allocated in %s [%u Bytes, generation %u]\n"#else	    "\tblock was allocated in %s [%u Bytes]\n"#endif	    "\terror was detected in  %s\n",	    PREV_STOP,	    B->StpA,	    B->File,	    (unsigned) B->Size,#ifdef GENERATIONS	    B->Generation,#endif	    file);  }  /* === begin of user data === */  if (B->StpB != PREV_STOP) {#if RM_TEST_DEPTH > 0    DoAbort = 1;#endif    fprintf(stderr, HEAD	    "Corrupted block begin (possibly written back)\n"	    "\tshould be: %08x\n"	    "\tis:        %08x\n"#ifdef GENERATIONS	    "\tblock was allocated in %s [%u Bytes, generation %u]\n"#else	    "\tblock was allocated in %s [%u Bytes]\n"#endif	    "\terror was detected in  %s\n",	    PREV_STOP,	    B->StpB,	    B->File,	    (unsigned) B->Size,#ifdef GENERATIONS	    B->Generation,#endif	    file);  }  /* === end of user data === */  if (memcmp(p+B->Size, &End, END_SPACE) != 0) {    unsigned char *E = (unsigned char *)(p+B->Size);    unsigned i;    int found = 0;#if RM_TEST_DEPTH > 0    DoAbort = 1;#endif    fprintf(stderr, HEAD	    "Corrupted block end (possibly written past the end)\n"	    "\tshould be:");    for (i = 0;   i < END_SPACE;   i++) {      fprintf(stderr, i%4 ? "%02x" : " %02x", End[i]);    }    fprintf(stderr,	    "\n\tis:       ");    for (i = 0;   i < END_SPACE;   i++) {      fprintf(stderr, i%sizeof(int) ? "%02x" : " %02x", E[i]);    }    fprintf(stderr, "\n"#ifdef GENERATIONS	    "\tblock was allocated in %s [%u Bytes, generation %u]\n"#else	    "\tblock was allocated in %s [%u Bytes]\n"#endif	    "\terror was detected in %s\n",	    B->File,	    (unsigned) B->Size,#ifdef GENERATIONS	    B->Generation,#endif	    file	    );#if RM_TEST_DEPTH > 0    if (!((unsigned long)E % sizeof(void *))   &&	!(*(unsigned long *)E % sizeof(void *))) {  /* because of alignment */      /* Special service: look if memory was overwritten with pointer */      if (FindBlk(*(unsigned char **)E)) {	begin *b = (begin *)((*(unsigned char **)E)-START_SPACE);	if (IsPossibleFilePos(b->File, b->Size)) {	  fprintf(stderr,		  "\tFirst %d bytes of overwritten memory can be interpreted\n"		  "\t\tas a pointer to a block "		  " allocated in:\n"#ifdef GENERATIONS		  "\t\t%s [%u Bytes, generation %u]\n",#else		  "\t\t%s [%u Bytes]\n",#endif		  (short)sizeof(void *),		  b->File,		  (unsigned short) b->Size#ifdef GENERATIONS		  , (unsigned short)b->Generation#endif		  );	  found = 1;	}      }    }    if (!found)#endif    {      /* Look, what we can find... */      int  j;      for (j = END_SPACE-1;   j >= 0;   j--) {	if (E[j] != End[j]) {	  break;	}      }      if (j >= 0   &&   !E[j]) {	/* Ends with '\0', so it's possibly a string */	if (j > 0) {	  while (--j >= 0) {	    if (!E[j]) {	      break;	    }	  }	  if (j < 0) {	    fprintf(stderr,		    "\tLooks somewhat like a too long string,\n"		    "\t\tending with \"%s\"\n",		    E);	  }	}	else {	  /* Off by one? */	  fprintf(stderr,		  "\tLooks like string allocated one byte too short\n"		  "\t\t(forgetting the nul byte)\n");	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -