LTP GCOV extension - code coverage report
Current view: directory - and-httpd/src - malloc-check.h
Test: And-httpd coverage
Date: 2006-09-11 Instrumented lines: 87
Code covered: 90.8 % Executed lines: 79

       1                 : #ifndef MALLOC_CHECK_H
       2                 : #define MALLOC_CHECK_H 1
       3                 : 
       4                 : typedef struct Malloc_check_vals
       5                 : {
       6                 :  void *ptr;
       7                 :  size_t sz;
       8                 :  const char *file;
       9                 :  unsigned int line;
      10                 : } Malloc_check_vals;
      11                 : 
      12                 : typedef struct Malloc_check_store
      13                 : {
      14                 :  unsigned long      mem_sz;
      15                 :  unsigned long      mem_num;
      16                 :  unsigned long      mem_fail_num;
      17                 :  Malloc_check_vals *mem_vals;
      18                 : } Malloc_check_store;
      19                 : 
      20                 : #ifndef  MALLOC_CHECK__ATTR_USED
      21                 : #ifdef __GNUC__
      22                 : # define MALLOC_CHECK__ATTR_USED() __attribute__((__used__))
      23                 : #else
      24                 : # define MALLOC_CHECK__ATTR_USED() /* do nothing */
      25                 : #endif
      26                 : #endif
      27                 : 
      28                 : #ifndef  MALLOC_CHECK__ATTR_H
      29                 : #ifdef __GNUC__
      30                 : # define MALLOC_CHECK__ATTR_H() __attribute__((__visibility__("hidden")))
      31                 : #else
      32                 : # define MALLOC_CHECK__ATTR_H() /* do nothing */
      33                 : #endif
      34                 : #endif
      35                 : 
      36                 : #ifndef  MALLOC_CHECK__ATTR_MALLOC
      37                 : #ifdef __GNUC__
      38                 : # define MALLOC_CHECK__ATTR_MALLOC() __attribute__ ((__malloc__))
      39                 : #else
      40                 : # define MALLOC_CHECK__ATTR_MALLOC() /* do nothing */
      41                 : #endif
      42                 : #endif
      43                 : 
      44                 : #ifndef MALLOC_CHECK_SUPPER_SCRUB /* never really call realloc() */
      45                 : #define MALLOC_CHECK_SUPPER_SCRUB 0
      46                 : #endif
      47                 : 
      48                 : #ifndef MALLOC_CHECK_STORE
      49                 : #define MALLOC_CHECK_STORE malloc_check__app_store
      50                 : #endif
      51                 : 
      52                 : /* NOTE: don't reset fail nums */
      53                 : #define MALLOC_CHECK_REINIT()                         \
      54                 :     MALLOC_CHECK_STORE.mem_sz = 0;                   \
      55                 :     MALLOC_CHECK_STORE.mem_num = 0;                  \
      56                 :     MALLOC_CHECK_STORE.mem_vals = NULL
      57                 : #define MALLOC_CHECK_INIT()                           \
      58                 :     MALLOC_CHECK_STORE.mem_fail_num = 0;             \
      59                 :     MALLOC_CHECK_REINIT()
      60                 : 
      61                 : #ifndef USE_MALLOC_CHECK
      62                 : #ifndef NDEBUG
      63                 : #  define USE_MALLOC_CHECK 1
      64                 : # else
      65                 : #  define USE_MALLOC_CHECK 0
      66                 : # endif
      67                 : #endif
      68                 : 
      69                 : #if !(USE_MALLOC_CHECK)
      70                 : #define MALLOC_CHECK_DECL()                                     \
      71                 :   static Malloc_check_store MALLOC_CHECK_STORE = {0, 0, 0, NULL}
      72                 : 
      73                 : # define MALLOC_CHECK_MEM(x) (1)
      74                 : # define MALLOC_CHECK_SZ_MEM(x, y) (1)
      75                 : # define MALLOC_CHECK_EMPTY() /* nothing */
      76                 : # define MALLOC_CHECK_DEC() (0)
      77                 : # define MALLOC_CHECK_FAIL_IN(x) /* nothing */
      78                 : # define MALLOC_CHECK_SCRUB_PTR(x, y)  /* nothing */
      79                 : 
      80                 : # define malloc_check_malloc(x, F, L)     malloc(x)
      81                 : # define malloc_check_calloc(x, y, F, L)  calloc(x, y)
      82                 : # define malloc_check_realloc(x, y, F, L) realloc(x, y)
      83                 : # define malloc_check_free(x)             free(x)
      84                 : #else
      85                 : 
      86                 : #include <stdio.h>
      87                 : 
      88                 : extern Malloc_check_store MALLOC_CHECK__ATTR_H() MALLOC_CHECK_STORE;
      89                 : 
      90                 : #define MALLOC_CHECK_DECL()                                     \
      91                 :     Malloc_check_store MALLOC_CHECK_STORE = {0, 0, 0, NULL}
      92                 : 
      93                 : # define MALLOC_CHECK_MEM(x)  malloc_check_mem(x)
      94                 : # define MALLOC_CHECK_SZ_MEM(x, y)  malloc_check_sz_mem(x, y)
      95                 : # define MALLOC_CHECK_EMPTY() malloc_check_empty()
      96                 : # define MALLOC_CHECK_DEC()                                             \
      97                 :     (MALLOC_CHECK_STORE.mem_fail_num && !--MALLOC_CHECK_STORE.mem_fail_num)
      98                 : # define MALLOC_CHECK_FAIL_IN(x) MALLOC_CHECK_STORE.mem_fail_num = (x)
      99                 : # define MALLOC_CHECK_SCRUB_PTR(x, y)  memset(x, 0xa5, y)
     100                 : 
     101                 : #ifndef MALLOC_CHECK_PRINT
     102                 : #define MALLOC_CHECK_PRINT 1
     103                 : #endif
     104                 : 
     105                 : #ifndef SWAP_TYPE
     106                 : #define SWAP_TYPE(x, y, type) do {              \
     107                 :       type internal_local_tmp = (x);            \
     108                 :       (x) = (y);                                \
     109                 :       (y) = internal_local_tmp;                 \
     110                 :     } while (FALSE)
     111                 : #endif
     112                 : 
     113                 : static void malloc_check_alloc(void)
     114                 :    MALLOC_CHECK__ATTR_USED();
     115                 : static unsigned int malloc_check_mem(const void *)
     116                 :    MALLOC_CHECK__ATTR_USED();
     117                 : static unsigned int malloc_check_sz_mem(const void *, size_t)
     118                 :    MALLOC_CHECK__ATTR_USED();
     119                 : static void *malloc_check_malloc(size_t, const char *, unsigned int)
     120                 :    MALLOC_CHECK__ATTR_MALLOC() MALLOC_CHECK__ATTR_USED();
     121                 : static void *malloc_check_calloc(size_t, size_t, const char *, unsigned int)
     122                 :    MALLOC_CHECK__ATTR_MALLOC() MALLOC_CHECK__ATTR_USED();
     123                 : static void malloc_check_free(void *)
     124                 :    MALLOC_CHECK__ATTR_USED();
     125                 : static void *malloc_check_realloc(void *, size_t,
     126                 :                                   const char *, unsigned int)
     127                 :    MALLOC_CHECK__ATTR_MALLOC() MALLOC_CHECK__ATTR_USED();
     128                 : static void malloc_check_empty(void)
     129                 :    MALLOC_CHECK__ATTR_USED();
     130                 : 
     131                 : static void malloc_check_alloc(void)
     132           53743 : {
     133           53743 :   size_t sz = MALLOC_CHECK_STORE.mem_sz;
     134                 :   
     135           53743 :   ++MALLOC_CHECK_STORE.mem_num;
     136                 : 
     137           53743 :   if (!MALLOC_CHECK_STORE.mem_sz)
     138                 :   {
     139             176 :     sz = 8;
     140             176 :     MALLOC_CHECK_STORE.mem_vals = malloc(sizeof(Malloc_check_vals) * sz);
     141                 :   }
     142           53567 :   else if (MALLOC_CHECK_STORE.mem_num > MALLOC_CHECK_STORE.mem_sz)
     143                 :   {
     144              54 :     sz *= 2;
     145              54 :     MALLOC_CHECK_STORE.mem_vals = realloc(MALLOC_CHECK_STORE.mem_vals,
     146                 :                                           sizeof(Malloc_check_vals) * sz);
     147                 :   }
     148           53743 :   ASSERT(MALLOC_CHECK_STORE.mem_num <= sz);
     149           53743 :   ASSERT(MALLOC_CHECK_STORE.mem_vals);
     150                 : 
     151           53743 :   MALLOC_CHECK_STORE.mem_sz = sz;
     152           53743 : }
     153                 : 
     154                 : static unsigned int malloc_check_mem(const void *ptr)
     155          203602 : {
     156          203602 :   unsigned int scan = 0;
     157                 : 
     158          203602 :   ASSERT(MALLOC_CHECK_STORE.mem_num);
     159                 :     
     160         4970614 :   while (MALLOC_CHECK_STORE.mem_vals[scan].ptr &&
     161                 :          (MALLOC_CHECK_STORE.mem_vals[scan].ptr != ptr))
     162         4767012 :     ++scan;
     163                 :   
     164          203602 :   ASSERT(MALLOC_CHECK_STORE.mem_vals[scan].ptr);
     165                 : 
     166          203602 :   return (scan);
     167                 : }
     168                 : 
     169                 : static unsigned int malloc_check_sz_mem(const void *ptr, size_t sz)
     170          121336 : {
     171          121336 :   unsigned int scan = malloc_check_mem(ptr);
     172                 : 
     173          121336 :   ASSERT(MALLOC_CHECK_STORE.mem_vals[scan].sz == sz);
     174                 : 
     175          121336 :   return (scan);
     176                 : }
     177                 : 
     178                 : static void *malloc_check_malloc(size_t sz, const char *file, unsigned int line)
     179           53743 : {
     180           53743 :   void *ret = NULL;
     181                 : 
     182           53743 :   if (MALLOC_CHECK_DEC())
     183               0 :     return (NULL);
     184                 : 
     185           53743 :   malloc_check_alloc();
     186                 : 
     187           53743 :   ASSERT(sz);
     188                 : 
     189           53743 :   ret = malloc(sz);
     190           53743 :   ASSERT_RET(ret, NULL);
     191                 :   
     192           53743 :   MALLOC_CHECK_SCRUB_PTR(ret, sz);
     193                 : 
     194           53743 :   MALLOC_CHECK_STORE.mem_vals[MALLOC_CHECK_STORE.mem_num - 1].ptr  = ret;
     195           53743 :   MALLOC_CHECK_STORE.mem_vals[MALLOC_CHECK_STORE.mem_num - 1].sz   = sz;
     196           53743 :   MALLOC_CHECK_STORE.mem_vals[MALLOC_CHECK_STORE.mem_num - 1].file = file;
     197           53743 :   MALLOC_CHECK_STORE.mem_vals[MALLOC_CHECK_STORE.mem_num - 1].line = line;
     198                 : 
     199           53743 :   return (ret);
     200                 : }
     201                 : 
     202                 : static void *malloc_check_calloc(size_t num, size_t sz,
     203                 :                                  const char *file, unsigned int line)
     204              32 : {
     205              32 :   size_t real_sz = num * sz;
     206              32 :   void *ret = NULL;
     207                 :   
     208              32 :   if ((num != 0) && ((real_sz / sz) != num))
     209               0 :     return (NULL);
     210              32 :   if (!(ret = malloc_check_malloc(real_sz, file, line)))
     211               0 :     return (NULL);
     212                 : 
     213              32 :   memset(ret, 0, real_sz);
     214              32 :   return (ret);
     215                 : }
     216                 : 
     217                 : static void malloc_check_free(void *ptr)
     218           71639 : {
     219           71639 :   if (ptr)
     220                 :   {
     221           53713 :     unsigned int scan = malloc_check_mem(ptr);
     222           53713 :     size_t sz = 0;
     223                 :     
     224           53713 :     ASSERT(MALLOC_CHECK_STORE.mem_num > 0);
     225           53713 :     --MALLOC_CHECK_STORE.mem_num;
     226                 : 
     227           53713 :     sz = MALLOC_CHECK_STORE.mem_vals[scan].sz;
     228           53713 :     if (scan != MALLOC_CHECK_STORE.mem_num)
     229                 :     {
     230            7076 :       unsigned int num = MALLOC_CHECK_STORE.mem_num;
     231            7076 :       Malloc_check_vals *val1 = &MALLOC_CHECK_STORE.mem_vals[scan];
     232            7076 :       Malloc_check_vals *val2 = &MALLOC_CHECK_STORE.mem_vals[num];
     233                 :       
     234            7076 :       SWAP_TYPE(val1->ptr,  val2->ptr,  void *);
     235            7076 :       SWAP_TYPE(val1->sz,   val2->sz,   size_t);
     236            7076 :       SWAP_TYPE(val1->file, val2->file, const char *);
     237            7076 :       SWAP_TYPE(val1->line, val2->line, unsigned int);
     238                 :     }
     239           53713 :     MALLOC_CHECK_STORE.mem_vals[MALLOC_CHECK_STORE.mem_num].ptr = NULL;
     240           53713 :     MALLOC_CHECK_SCRUB_PTR(ptr, sz);
     241           53713 :     free(ptr);
     242                 :   }
     243           71639 : }
     244                 : 
     245                 : static void *malloc_check_realloc(void *ptr, size_t sz,
     246                 :                                   const char *file, unsigned int line)
     247           28553 : {
     248           28553 :   void *ret = NULL;
     249           28553 :   unsigned int scan = malloc_check_mem(ptr);
     250                 : 
     251           28553 :   ASSERT(ptr && sz);
     252                 : 
     253                 :   if (MALLOC_CHECK_SUPPER_SCRUB)
     254                 :   {
     255                 :     if (!(ret = malloc_check_malloc(sz, file, line)))
     256                 :       return (NULL);
     257                 : 
     258                 :     if (sz >= MALLOC_CHECK_STORE.mem_vals[scan].sz)
     259                 :       sz = MALLOC_CHECK_STORE.mem_vals[scan].sz;
     260                 :     if (sz)
     261                 :       memcpy(ret, ptr, sz);
     262                 :     
     263                 :     malloc_check_free(ptr);
     264                 :     
     265                 :     return (ret);
     266                 :   }
     267                 : 
     268           28553 :   if (MALLOC_CHECK_DEC())
     269               0 :     return (NULL);
     270                 : 
     271           28553 :   ret = realloc(ptr, sz);
     272           28553 :   ASSERT_RET(ret, NULL);
     273                 : 
     274                 :   /* note we can't scrub ... :( */
     275           28553 :   MALLOC_CHECK_STORE.mem_vals[scan].ptr  = ret;
     276           28553 :   MALLOC_CHECK_STORE.mem_vals[scan].sz   = sz;
     277           28553 :   MALLOC_CHECK_STORE.mem_vals[scan].file = file;
     278           28553 :   MALLOC_CHECK_STORE.mem_vals[scan].line = line;
     279                 : 
     280           28553 :   return (ret);
     281                 : }
     282                 : 
     283                 : static void malloc_check_empty(void)
     284             166 : {
     285             166 :   if (MALLOC_CHECK_PRINT && MALLOC_CHECK_STORE.mem_num)
     286                 :   {
     287               0 :     unsigned int scan = 0;
     288                 : 
     289               0 :     while (MALLOC_CHECK_STORE.mem_vals[scan].ptr)
     290                 :     {
     291               0 :       fprintf(stderr, " FAILED MEM CHECK EMPTY: ptr %p, sz %zu, from %u:%s\n",
     292                 :               MALLOC_CHECK_STORE.mem_vals[scan].ptr,
     293                 :               MALLOC_CHECK_STORE.mem_vals[scan].sz,
     294                 :               MALLOC_CHECK_STORE.mem_vals[scan].line,
     295                 :               MALLOC_CHECK_STORE.mem_vals[scan].file);
     296               0 :       ++scan;
     297                 :     }
     298                 :   }
     299             166 :   ASSERT(!MALLOC_CHECK_STORE.mem_num);
     300             166 : }
     301                 : #endif
     302                 : 
     303                 : #endif

Generated by: LTP GCOV extension version 1.4