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

  1. /*
  2.  * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  3.  *
  4.  * This software may be distributed freely as long as the following conditions
  5.  * are met:
  6.  *         * the distribution, or any derivative thereof, may not be
  7.  *          included as part of a commercial product
  8.  *        * full source code is provided including this copyright
  9.  *        * there is no charge for the software itself (there may be
  10.  *          a minimal charge for the copying or distribution effort)
  11.  *        * this copyright notice is not modified or removed from any
  12.  *          source file
  13.  */
  14. #include <stdio.h>
  15. #include "mallocin.h"
  16.  
  17. static long     fillmalloc = -1;
  18. static long     fillfree   = -1;
  19.  
  20. #define FILLINIT() if( fillmalloc == -1 )  FillInit()
  21.  
  22.  
  23. /*
  24.  * Fill check types
  25.  */
  26. #define FILL_UNDER     1
  27. #define FILL_OVER    2
  28. #define FILL_FREED    3
  29.  
  30. /*
  31.  * FillInit() - fill initialization routine
  32.  */
  33. VOIDTYPE
  34. FillInit()
  35. {
  36.     char    * ptr;
  37.     int      i;
  38.     
  39.     ptr = (char *) &fillmalloc;
  40.  
  41.     for( i=0; i < sizeof(long); i++)
  42.     {
  43.         *ptr++ = M_FILL;
  44.     }
  45.  
  46.     ptr = (char *) &fillfree;
  47.  
  48.     for( i=0; i < sizeof(long); i++)
  49.     {
  50.         *ptr++ = M_FREE_FILL;
  51.     }
  52.  
  53. } /* FillInit(... */
  54.  
  55. /*
  56.  * FillCheck()    check for overflow and/or underflow using the filled regions
  57.  *        in the specified malloc segment.
  58.  */
  59. int
  60. FillCheck(func,file,line,ptr,showerrors)
  61.     CONST char    * func;
  62.     CONST char    * file;
  63.     int          line;
  64.     struct mlist    * ptr;
  65.     int          showerrors;
  66. {
  67.     int          rtn = -1;
  68.  
  69.     FILLINIT();
  70.  
  71.     /*
  72.      * if this block has no filling
  73.      */
  74.     if( (ptr->flag & (M_FILLED|M_DFILLED)) == 0 )
  75.     {
  76.         rtn = 0;
  77.     }
  78.     /*
  79.      * else if this block is in use or it was not free-filled
  80.      */
  81.     else if(    ((ptr->flag & M_INUSE)  != 0) 
  82.          || ((ptr->flag & M_FILLED) == 0) )
  83.     {
  84.         /*
  85.          * check for data underflow and data overflow
  86.          */
  87.         rtn =   FillCheckData(func,file,line,ptr,FILL_UNDER,showerrors)
  88.               + FillCheckData(func,file,line,ptr,FILL_OVER, showerrors);
  89.     }
  90.     /*
  91.      * else the block must have been freed
  92.      */
  93.     else
  94.     {
  95.         /*
  96.          * check for data underflow and free filling
  97.          */
  98.         rtn =   FillCheckData(func,file,line,ptr,FILL_UNDER,showerrors)
  99.               + FillCheckData(func,file,line,ptr,FILL_FREED,showerrors);
  100.     }
  101.  
  102.     return(rtn);
  103.  
  104. } /* FillCheck(... */
  105.  
  106. /*
  107.  * FillCheckData() - routine to check the data areas to ensure that they
  108.  *          are filled with the appropriate fill characters.
  109.  */
  110. int
  111. FillCheckData(func,file,line,ptr,checktype,showerrors)
  112.     CONST char    * func;
  113.     CONST char    * file;
  114.     int          line;
  115.     struct mlist    * ptr;
  116.     int          checktype;
  117.     int          showerrors;
  118. {
  119.     register char        * data = NULL;
  120.     int              errcode = 0;
  121.     char              filler = '\0';
  122.     long              fillword = 0;
  123.     register SIZETYPE      i = 0;
  124.     register long        * ldata;
  125.     SIZETYPE          limit = ptr->s.size;
  126.     int              rtn = -1;
  127.  
  128.     if( (ptr->flag & (M_DFILLED | M_FILLED)) == 0 )
  129.     {
  130.         return(0);
  131.     }
  132.  
  133.     switch(checktype)
  134.     {
  135.         case FILL_UNDER:
  136.             if(    ((ptr->flag & M_DFILLED) == 0 )
  137.                 || (ptr->s.filler[LONGFILL-1] == fillmalloc) )
  138.             {
  139.                 rtn = 0;
  140.             }
  141.             else
  142.             {
  143.  
  144.                 /*
  145.                  * if showing errors
  146.                   */
  147.                 if( showerrors )
  148.                 {
  149.                     /*
  150.                      * give the underrun error message
  151.                      */
  152.                     malloc_errno = M_CODE_UNDERRUN;
  153.                     malloc_warning(func,file,line,ptr);
  154.                     /*
  155.                      * fix the problem
  156.                      */
  157.                     ptr->s.filler[LONGFILL-1] = fillmalloc;
  158.                 }
  159.                 rtn = 1;
  160.             }
  161.             break;
  162.  
  163.         case FILL_OVER:
  164.             if( (ptr->flag & M_DFILLED) == 0)
  165.             {
  166.                 rtn = 0;
  167.             }
  168.             else
  169.             {
  170.                 i        = ptr->r_size;
  171.                 errcode  = M_CODE_OVERRUN;
  172.                 filler   = M_FILL;
  173.                 fillword = fillmalloc;
  174.                 data     = ptr->data;
  175.             }
  176.             break;
  177.  
  178.         case FILL_FREED:
  179.             if( (ptr->flag & M_FILLED) == 0)
  180.             {
  181.                 rtn = 0;
  182.             }
  183.             else
  184.             {
  185.                 i        = 0;
  186.                 errcode  = M_CODE_REUSE;
  187.                 filler   = M_FREE_FILL;
  188.                 fillword = fillfree;
  189.                 data     = ptr->data;
  190.             }
  191.             break;
  192.  
  193.         default:
  194.             i = 0; 
  195.             limit = 0;
  196.             break;
  197.     }
  198.  
  199.     /*
  200.      * if there is nothing to check, just return 
  201.      */
  202.     if( rtn != -1 )
  203.     {
  204.         return(rtn);
  205.     }
  206.             
  207.     rtn = 0;
  208.     data += i;
  209.     i = limit - i;
  210.     while( ((long)data) & (sizeof(long)-1) )
  211.     {
  212.         if( *data != filler )
  213.         {
  214.             if( showerrors )
  215.             {
  216.                 malloc_errno = errcode;
  217.                 malloc_warning(func,file,line,ptr);
  218.  
  219.                 /*
  220.                  * fix the underrun so we only get this
  221.                  * message once
  222.                  */
  223.                 while( i-- > 0 )
  224.                 {
  225.                     *(data++) = filler;
  226.                 }
  227.             }
  228.  
  229.             rtn++;
  230.                     
  231.             break;
  232.         }
  233.         data++;
  234.         i--;
  235.     }
  236.  
  237.     /*
  238.      * if we haven't found an error yet
  239.      */
  240.     if( rtn == 0 )
  241.     {
  242.         /*
  243.          * convert to use longword pointer
  244.          */
  245.         ldata = (long *) data;
  246.         i >>= 2;
  247.  
  248.         /*
  249.          * while more longwords to check
  250.          */    
  251.         while( i > 0 )
  252.         {
  253.             if( *ldata != fillword )
  254.             {
  255.                 if( showerrors )
  256.                 {
  257.                     malloc_errno = errcode;
  258.                     malloc_warning(func,file,line,ptr);
  259.     
  260.                     /*
  261.                      * fix the underrun so we only get this
  262.                      * message once
  263.                      */
  264.                     while( i-- > 0 )
  265.                     {
  266.                         *(ldata++) = fillword;
  267.                     }
  268.                 }
  269.     
  270.                 rtn++;
  271.                 break;
  272.             }
  273.  
  274.             ldata++;
  275.             i--;
  276.         
  277.         }
  278.         
  279.     }
  280.  
  281.     return(rtn);
  282.  
  283. } /* FillCheckData(... */
  284.  
  285. /*
  286.  * FillData()    fill in the needed areas in the specified segment.  This is used
  287.  *        to place non-zero data in new malloc segments, setup boundary
  288.  *        areas to catch under/overflow, and overwrite freed segments so 
  289.  *        that they can't be usefully re-used.
  290.  */
  291. void
  292. FillData(ptr,alloctype,start,nextptr)
  293.     register struct mlist    * ptr;
  294.     int              alloctype;
  295.     SIZETYPE          start;
  296.     struct mlist        * nextptr;
  297. {
  298.     int          fills;
  299.     int          filler = 0;
  300.     SIZETYPE      limit = ptr->s.size;
  301.     
  302.     FILLINIT();
  303.  
  304.     if( (malloc_opts & (MOPT_MFILL|MOPT_DFILL|MOPT_FFILL)) == 0)
  305.     {
  306.         ptr->flag &= ~(M_FILLED|M_DFILLED);
  307.         return;
  308.     }
  309.  
  310.     switch(alloctype)
  311.     {
  312.         case FILL_MALLOC:
  313.             fills = MOPT_MFILL | MOPT_DFILL;
  314.             filler = M_FILL;
  315.             break;
  316.  
  317.         case FILL_FREE:
  318.             fills = MOPT_FFILL;
  319.             filler = M_FREE_FILL;
  320.             break;
  321.  
  322.         case FILL_SPLIT:
  323.             fills = MOPT_FFILL;
  324.             filler = M_FREE_FILL;
  325.             break;
  326.  
  327.         case FILL_JOIN:
  328.             if( (ptr->flag&M_INUSE) != 0 )
  329.             {
  330.                 if( ptr->flag & M_FILLED )
  331.                 {
  332.                     fills = MOPT_MFILL;
  333.                     filler = M_FILL;
  334.                 }
  335.                 else if(  ptr->flag & M_DFILLED )
  336.                 {
  337.                     fills = MOPT_MFILL;
  338.                     filler = M_FILL;
  339.                     start = ptr->r_size;;
  340.                 }
  341.                 else
  342.                 {
  343.                     fills = 0;
  344.                 }
  345.             }
  346.             else /* not in use */
  347.             {
  348.                 /*
  349.                  * if this segment has bee free-filled
  350.                  */
  351.                 if( ptr->flag & M_FILLED )
  352.                 {
  353.                     fills = MOPT_MFILL;
  354.                     filler = M_FREE_FILL;
  355.  
  356.                     /*
  357.                      * if the next segment is already filled
  358.                      */
  359.                     if( (nextptr->flag & M_FILLED) != 0 )
  360.                     {
  361.                         limit = start + M_SIZE;
  362.                     }
  363.                 }
  364.                 /*
  365.                  * else if this segment has overflow filling
  366.                  * enabled, fill the next segment since it is
  367.                  * now overflow of this segment.
  368.                  */
  369.                 else if( (ptr->flag & M_DFILLED) != 0 )
  370.                 {
  371.                     fills = MOPT_DFILL;
  372.                     filler = M_FILL;
  373.                     start = ptr->r_size;;
  374.                 }
  375.                 else
  376.                 {
  377.                     fills = 0;
  378.                 }
  379.             }
  380.             break;
  381.  
  382.         case FILL_REALLOC:
  383.             if( ptr->flag & M_FILLED )
  384.             {
  385.                 fills = MOPT_MFILL;
  386.                 filler = M_FILL;
  387.             }
  388.             else if( ptr->flag & M_DFILLED )
  389.             {
  390.                 fills = MOPT_MFILL;
  391.                 filler = M_FILL;
  392.                 start = ptr->r_size;;
  393.             }
  394.             else
  395.             {
  396.                 fills = 0;
  397.             }
  398.             break;
  399.  
  400.         case FILL_CALLOC:
  401.             fills = MOPT_DFILL;
  402.             break;
  403.  
  404.         default:
  405.             fills = 0;
  406.     }
  407.  
  408.  
  409.     if( (fills & MOPT_DFILL) != 0 )
  410.     {
  411.         if( (malloc_opts & MOPT_DFILL) != 0 )
  412.         {
  413.             ptr->s.filler[LONGFILL-1] = fillmalloc;
  414.             ptr->flag |= M_DFILLED;
  415.         }
  416.         else if( alloctype != FILL_FREE ) 
  417.         {
  418.             ptr->flag &= ~M_DFILLED;
  419.         }
  420.     }
  421.  
  422.     if( (malloc_opts & (MOPT_MFILL|MOPT_FFILL) & fills) != 0 )
  423.     {
  424.         /*
  425.          * fill in the data
  426.          */
  427.         DataMS(ptr->data+start, filler, (MEMSIZE) (limit - start));
  428.  
  429.         ptr->flag |= M_FILLED;
  430.     }
  431.     else 
  432.     {
  433.         ptr->flag &= ~M_FILLED;
  434.  
  435.         /*
  436.          * if we still have to fill the boundry area and this isn't 
  437.          * a free-fill, go do it
  438.          */
  439.         if( ((ptr->flag & M_DFILLED) != 0) && (filler == M_FILL) )
  440.         {
  441.             DataMS(ptr->data+ptr->r_size, M_FILL, 
  442.                     (MEMSIZE) (limit - ptr->r_size));
  443.         }
  444.  
  445.     }
  446.  
  447. } /* FillData(... */
  448.  
  449.