home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dbmalloc.zip / mchain.c < prev    next >
C/C++ Source or Header  |  1993-01-04  |  6KB  |  261 lines

  1.  
  2. /*
  3.  * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  4.  *
  5.  * This software may be distributed freely as long as the following conditions
  6.  * are met:
  7.  *         * the distribution, or any derivative thereof, may not be
  8.  *          included as part of a commercial product
  9.  *        * full source code is provided including this copyright
  10.  *        * there is no charge for the software itself (there may be
  11.  *          a minimal charge for the copying or distribution effort)
  12.  *        * this copyright notice is not modified or removed from any
  13.  *          source file
  14.  */
  15. #include <stdio.h>
  16. #include <fcntl.h>
  17. #include "mallocin.h"
  18.  
  19. /*
  20.  * Function:    malloc_chain_check()
  21.  *
  22.  * Purpose:    to verify malloc chain is intact
  23.  *
  24.  * Arguments:    todo    - 0 - just check and return status
  25.  *              1 - call malloc_warn if error detected
  26.  *
  27.  * Returns:    0    - malloc chain intact & no overflows
  28.  *        other    - problems detected in malloc chain
  29.  *
  30.  * Narrative:
  31.  *
  32.  * Notes:    If todo is non-zero the malloc_warn function, when called
  33.  *        may not return (i.e. it may exit)
  34.  *
  35.  */
  36. #ifndef lint
  37. static
  38. char rcs_hdr[] = "$Id: mchain.c,v 1.14 1992/08/22 16:27:13 cpcahil Exp $";
  39. #endif
  40.  
  41.  
  42. int
  43. malloc_chain_check(todo)
  44.     int          todo;
  45. {
  46.     return( DBmalloc_chain_check( (char *)NULL, 0, todo) );
  47. }
  48.  
  49. int
  50. DBmalloc_chain_check(file,line,todo)
  51.     CONST char    * file;
  52.     int          line;
  53.     int          todo;
  54. {
  55.     return( DBFmalloc_chain_check("malloc_chain_check",file,line,todo) );
  56. }
  57.  
  58. int
  59. DBFmalloc_chain_check(func,file,line,todo)
  60.     CONST char    * func;
  61.     CONST char    * file;
  62.     int          line;
  63.     int          todo;
  64. {
  65.     register struct mlist    * oldptr;
  66.     register struct mlist    * ptr;
  67.     int              rtn = 0;
  68.  
  69.     MALLOC_INIT();
  70.  
  71.     /*
  72.      * first check the full malloc chain
  73.      */
  74.     oldptr = &malloc_start;
  75.     for(ptr = malloc_start.next; ; oldptr = ptr, ptr = ptr->next)
  76.     {
  77.         /*
  78.          * Since the malloc chain is a forward only chain, any
  79.          * pointer that we get should always be positioned in 
  80.          * memory following the previous pointer.  If this is not
  81.          * so, we must have a corrupted chain.
  82.          */
  83.         if( ptr )
  84.         {
  85.             if(ptr < oldptr )
  86.             {
  87.                 malloc_errno = M_CODE_CHAIN_BROKE;
  88.                 if( todo )
  89.                 {
  90.                     malloc_fatal(func,file,line,oldptr);
  91.                 }
  92.                 rtn++;
  93.                 break;
  94.             }
  95.         }
  96.         else
  97.         {
  98.             if( malloc_end && (oldptr != malloc_end) )
  99.             {
  100.                 /*
  101.                  * This should never happen.  If it does, then
  102.                  * we got a real problem.
  103.                  */
  104.                 malloc_errno = M_CODE_NO_END;
  105.                 if( todo )
  106.                 {
  107.                     malloc_fatal(func,file,line,oldptr);
  108.                 }
  109.                 rtn++;
  110.             }
  111.             break;
  112.         }
  113.         
  114.         /*
  115.          * verify that ptr is within the malloc region...
  116.          * since we started within the malloc chain this should never
  117.          * happen.
  118.          */
  119.         if(    ((DATATYPE *)ptr < malloc_data_start)
  120.             || ((DATATYPE *)ptr > malloc_data_end) 
  121.             || ((((long)ptr) & malloc_round) != 0) )
  122.         {
  123.             malloc_errno = M_CODE_BAD_PTR;
  124.             if( todo )
  125.             {
  126.                 malloc_fatal(func,file,line,oldptr);
  127.             }
  128.             rtn++;
  129.             break;
  130.         }
  131.  
  132.         /* 
  133.          * verify magic flag is set
  134.          */
  135.         if( (ptr->flag&M_MAGIC_BITS) != M_MAGIC )
  136.         {
  137.             malloc_errno = M_CODE_BAD_MAGIC;
  138.             if( todo )
  139.             {
  140.                 malloc_warning(func,file,line,
  141.                         (struct mlist *)NULL);
  142.             }
  143.             rtn++;
  144.             continue;
  145.         }
  146.  
  147.         /* 
  148.          * verify segments are correctly linked together
  149.          */
  150.         if( (ptr->prev && (ptr->prev->next != ptr) ) ||
  151.             (ptr->next && (ptr->next->prev != ptr) ) ||
  152.             ((ptr->next == NULL) && (ptr->prev == NULL)) )
  153.         {
  154.             malloc_errno = M_CODE_BAD_CONNECT;
  155.             if( todo )
  156.             {
  157.                 malloc_warning(func,file,line,ptr);
  158.             }
  159.             rtn++;
  160.             continue;
  161.         }
  162.  
  163.         /*
  164.          * check for under and/or overflow on this segment
  165.          */
  166.         rtn +=  FILLCHECK(func,file,line,ptr,todo);
  167.  
  168.     } /* for(... */
  169.  
  170.     /*
  171.      * and now check the free list
  172.      */
  173.     oldptr = NULL;
  174.     for(ptr=malloc_freelist; (rtn == 0) && (ptr != NULL); ptr=ptr->freenext)
  175.     {
  176.         /*
  177.          * Since the malloc chain is a forward only chain, any
  178.          * pointer that we get should always be positioned in 
  179.          * memory following the previous pointer.  If this is not
  180.          * so, we must have a corrupted chain.
  181.          */
  182.         if( (oldptr != NULL) && (ptr < oldptr) )
  183.         {
  184.             malloc_errno = M_CODE_CHAIN_BROKE;
  185.             if( todo )
  186.             {
  187.                 malloc_fatal(func,file,line,oldptr);
  188.             }
  189.             rtn++;
  190.         }
  191.         /*
  192.          * verify that ptr is within the malloc region...
  193.          * since we started within the malloc chain this should never
  194.          * happen.
  195.          */
  196.         else if(    ((DATATYPE *)ptr < malloc_data_start)
  197.                  || ((DATATYPE *)ptr > malloc_data_end) 
  198.                       || ((((long)ptr) & malloc_round) != 0) )
  199.         {
  200.             malloc_errno = M_CODE_BAD_PTR;
  201.             if( todo )
  202.             {
  203.                 malloc_fatal(func,file,line,oldptr);
  204.             }
  205.             rtn++;
  206.         }
  207.         /* 
  208.          * verify magic flag is set
  209.          */
  210.         else if( (ptr->flag&M_MAGIC_BITS) != M_MAGIC )
  211.         {
  212.             malloc_errno = M_CODE_BAD_MAGIC;
  213.             if( todo )
  214.             {
  215.                 malloc_warning(func,file,line,
  216.                         (struct mlist *)NULL);
  217.             }
  218.             rtn++;
  219.         }
  220.         /* 
  221.          * verify segments are correctly linked together
  222.          */
  223.         else if(   (ptr->freeprev && (ptr->freeprev->freenext != ptr) )
  224.             || (ptr->freenext && (ptr->freenext->freeprev != ptr) ))
  225.         {
  226.             malloc_errno = M_CODE_BAD_CONNECT;
  227.             if( todo )
  228.             {
  229.                 malloc_warning(func,file,line,ptr);
  230.             }
  231.             rtn++;
  232.         }
  233.         /*
  234.          * else if this segment is in use
  235.          */
  236.         else if( (ptr->flag & M_INUSE) != 0 )
  237.         {
  238.             malloc_errno = M_CODE_FREELIST_BAD;
  239.             if( todo )
  240.             {
  241.                 malloc_warning(func,file, line,ptr);
  242.             }
  243.             rtn++;
  244.         }
  245.         /*
  246.          * else we have to check the filled areas.
  247.          */
  248.         else
  249.         {
  250.             /*
  251.              * check for underflow and/or reuse of this segment
  252.              */
  253.             rtn +=  FILLCHECK(func,file,line,ptr,todo);
  254.         }
  255.  
  256.     } /* for(... */
  257.  
  258.     return(rtn);
  259.  
  260. } /* malloc_chain_check(... */
  261.