home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / VILE327.ZIP / VILE327.TAR / vile3.27 / vmalloc.c < prev    next >
C/C++ Source or Header  |  1992-12-14  |  8KB  |  393 lines

  1. #include "estruct.h"
  2. #include "edef.h"
  3. #if ! SMALLER && LATER
  4. # include "evar.h"
  5. #endif
  6.  
  7. /* these routines copied without permission from "The C User's Journal",
  8.  *    issue of Feb. 1989.  I assume they are Copyright 1989 by them.
  9.  *    They and the accompanying article were written by Eric White.
  10.  *    (pgf, 1989)
  11.  *
  12.  * $Log: vmalloc.c,v $
  13.  * Revision 1.7  1992/07/22  00:51:35  foxharp
  14.  * took out the counters -- they no longer compile correctly
  15.  *
  16.  * Revision 1.6  1992/05/16  12:00:31  pgf
  17.  * prototypes/ansi/void-int stuff/microsoftC
  18.  *
  19.  * Revision 1.5  1992/03/05  09:19:55  pgf
  20.  * changed some mlwrite() to mlforce(), due to new terse support
  21.  *
  22.  * Revision 1.4  1991/11/01  14:38:00  pgf
  23.  * saber cleanup
  24.  *
  25.  * Revision 1.3  1991/10/08  01:30:59  pgf
  26.  * brought up to date, and ifdef LATER'd some stuff in
  27.  * the accounting section -- doesn't work due to header inclusion
  28.  * problems
  29.  *
  30.  * Revision 1.2  1991/08/07  12:35:07  pgf
  31.  * added RCS log messages
  32.  *
  33.  * revision 1.1
  34.  * date: 1990/09/21 10:26:17;
  35.  * initial vile RCS revision
  36.  */
  37.  
  38. #if VMALLOC
  39.  
  40. #undef malloc
  41. #undef free
  42. #undef realloc
  43. #undef calloc
  44. #undef vverify
  45.  
  46. #include "stdio.h"
  47. #include "string.h"
  48.  
  49. char *malloc(), *calloc(), *realloc();
  50.  
  51. char *vmalloc();
  52. void vfree();
  53. void rvverify();
  54. char *vrealloc();
  55. char *vcalloc();
  56. void vdump();
  57.  
  58.  
  59. /* max buffers alloced but not yet freed */
  60. #define MAXMALLOCS 20000
  61.  
  62. /* known pattern, and how many of them */
  63. #define KP 0xaaaaaaaaL
  64. #define KPW (2*sizeof(unsigned long))
  65.  
  66.  
  67. static void trace();
  68. static void errout();
  69.  
  70. static int nummallocs = 0;
  71. struct mtype {
  72.     unsigned char *addr;
  73.     int size;
  74. };
  75.  
  76. static struct mtype m[MAXMALLOCS];
  77.  
  78. #define VMAL 1
  79. #define VFRE 2
  80. #define VREA 4
  81. int doverifys = VMAL|VREA;  /* |VFRE */
  82.  
  83. static void
  84. dumpbuf(x)
  85. int x;
  86. {
  87.     unsigned char *c;
  88.     char s [80];
  89.     c = (unsigned char *)m[x].addr - 2;
  90.     /* dump malloc buffer to the vmalloc file */
  91.     while (c <= m[x].addr + m[x].size + KPW + KPW + 1) {
  92.         sprintf(s, "%04.4lx : %02x ", (long)c, *c);
  93.         if (c == m[x].addr)
  94.             strcat(s," <= leading known pattern");
  95.         if (c == m[x].addr + KPW)
  96.             strcat(s," <= addr of malloc buffer");
  97.         if (c == m[x].addr + m[x].size + KPW)
  98.             strcat(s," <= trailing known pattern");
  99.         strcat(s,"\n");
  100.         trace(s);
  101.         ++c;
  102.     }
  103. }
  104.         
  105. void
  106. rvverify(id,f,l)
  107. char *id;
  108. char *f;
  109. {
  110.     char s[80];
  111.     register int c;
  112.     register struct mtype *mp;
  113.  
  114.     
  115.     /* verify entire malloc heap */
  116.     for (mp = &m[nummallocs-1]; mp >= m; mp--) {
  117.         if (mp->addr != NULL) {
  118.             if (*(ulong *)mp->addr != KP || 
  119.                 *(ulong *)(mp->addr + sizeof (ulong)) != KP)
  120.             {
  121.                 sprintf(s, 
  122.         "ERROR: Malloc area corrupted (%s). %s %d\n",
  123.                              id,f,l);
  124.                 fputs(s,stderr);
  125.                 trace(s);
  126.                 dumpbuf(mp - m);
  127.                 errout();
  128.             }
  129.         }
  130.     }
  131. }        
  132.  
  133. char *
  134. vmalloc(size,f,l)
  135. char *f;
  136. {
  137.     unsigned char *buffer;
  138.     char *sp, s[80];
  139.     register int c;
  140.     register struct mtype *mp;
  141.  
  142.     if (doverifys & VMAL)
  143.         rvverify("vmalloc",f,l);
  144.     if (( buffer = (unsigned char *)malloc(size + KPW + KPW)) == NULL) {
  145.         sp = "ERROR: real malloc returned NULL\n";
  146.         fprintf(stderr,sp);
  147.         trace(sp);
  148.         errout();
  149.     }
  150. #ifdef VERBOSE
  151.     sprintf(s,"%04.4lx:vmalloc size = %ld, %s %d\n",
  152.         (long)buffer,(long)size,f,l);
  153.     trace(s);
  154. #endif
  155.     /* find a place for an entry in m */
  156.     for (mp = m; mp < &m[MAXMALLOCS] && mp->addr != NULL; ++mp)
  157.         ;
  158.     if (mp == &m[MAXMALLOCS]) {
  159.         sp = "ERROR: too many mallocs\n";
  160.         fprintf(stderr,sp);
  161.         trace(sp);
  162.         errout();
  163.     }
  164.     mp->addr = buffer;
  165.     mp->size = size;
  166.     if (mp == &m[nummallocs])
  167.         ++nummallocs;
  168.     *(ulong *)(mp->addr) = KP;
  169.     *(ulong *)(mp->addr + sizeof(ulong)) = KP;
  170.     return (char *)(buffer + KPW);
  171. }
  172.  
  173. char *
  174. vcalloc(n,size,f,l)
  175. int n, size;
  176. char *f;
  177. {
  178.     return vmalloc(n * size,f,l);
  179. }
  180.  
  181. void
  182. vfree(buffer,f,l)
  183. unsigned char *buffer;
  184. char *f;
  185. {
  186.     unsigned char *b;
  187.     char s[80], *sp;
  188.     register struct mtype *mp;
  189.  
  190.     b = buffer - KPW;
  191.     if (doverifys & VFRE)
  192.         rvverify("vfree",f,l);
  193.     for (mp = &m[nummallocs-1]; mp >= m && mp->addr != b; mp--)
  194.         ;
  195.     if (mp < m) {
  196.         sprintf(s,"ERROR: location to free is not in list. %s %d\n",
  197.                      f,l);
  198.         fprintf(stderr,s);
  199.         trace(s);
  200.         errout();
  201.     }
  202. #ifdef VERBOSE
  203.     sprintf(s,"%04.4lx:vfree %s %d\n",(long)b,f,l);
  204.     trace(s);
  205. #endif
  206.     if (*(ulong *)mp->addr != KP || 
  207.         *(ulong *)(mp->addr + sizeof (ulong)) != KP)
  208.     {
  209.         sprintf(s,"ERROR: corrupted freed block. %s %d\n", f,l);
  210.         fprintf(stderr,s);
  211.         trace(s);
  212.         errout();
  213.     }
  214.     free(b);
  215.     mp->addr = NULL;
  216.     if (mp == &m[nummallocs-1])
  217.         --nummallocs;
  218. }
  219.  
  220. char *
  221. vrealloc(buffer,size,f,l)
  222. unsigned char *buffer;
  223. int size;
  224. char *f;
  225. {
  226.     unsigned char *b, *b2;
  227.     char *sp, s[80];
  228.     register int c;
  229.     register struct mtype *mp;
  230.  
  231.     b = buffer - KPW;
  232.     if (doverifys & VREA)
  233.         rvverify("vrealloc",f,l);
  234.  
  235.     for (mp = &m[nummallocs-1]; mp >= m && mp->addr != b; mp--)
  236.         ;
  237.     if (mp < m) {
  238.         sprintf(s,"ERROR: location to realloc is not in list. %s %d\n",
  239.                      sp,f,l);
  240.         fprintf(stderr,s);
  241.         trace(s);
  242.         errout();
  243.     }
  244.  
  245. #ifdef VERBOSE
  246.     sprintf(s,"%04.4lx:vrealloc size = %ld, %s %d\n",
  247.             (long)b,(long)size,f,l);
  248.     trace(s);
  249. #endif
  250.     *(ulong *)(mp->addr) = KP;
  251.     *(ulong *)(mp->addr + sizeof (ulong)) = KP;
  252.     b2 = (unsigned char *)realloc(b,size+KPW+KPW);
  253.     *(ulong *)(mp->addr + mp->size + KPW) = KP;
  254.     *(ulong *)(mp->addr + mp->size + KPW + sizeof (ulong)) = KP;
  255.     return (char *)(b2 + KPW);
  256. }
  257.  
  258. void
  259. vdump(id)
  260. char *id;
  261. {
  262.     char s[80];
  263.     int x;
  264.     sprintf(s,"=============Dump of malloc heap==========%s\n",id);
  265.     trace(s);
  266.     for (x = 0; x < nummallocs; ++x) {
  267.         if (m[x].addr != NULL) {
  268.             sprintf(s,"=========malloc buffer addr: %04.4lx\n",
  269.                 (long)m[x].addr);
  270.             trace(s);
  271.             sprintf(s,"=========malloc buffer size: %04x\n",
  272.                 (long)m[x].size + KPW + KPW);
  273.             trace(s);
  274.             dumpbuf(x);
  275.         }
  276.     }
  277. }
  278.  
  279. static void
  280. trace(s)
  281. char *s;
  282. {
  283.     static FILE *out = NULL;
  284.     if (out == NULL) {
  285.         unlink("vmalloc.log");
  286.         out = fopen("vmalloc.log", "w");
  287.         setbuf(out,NULL);
  288.     }
  289.     fputs(s,out);
  290. }
  291.     
  292. static void
  293. errout()
  294. {
  295.     sleep(1);
  296.     kill(getpid(),3);
  297.     pause();
  298. }
  299.  
  300. int
  301. setvmalloc(f,n)
  302. int f,n;
  303. {
  304.     register struct mtype *mp;
  305.     int i,num,found;
  306.     
  307.     if (f)
  308.         doverifys = n;
  309.     rvverify("requested",__FILE__,__LINE__);
  310. #if COUNT_THEM
  311.     for (mp = m, num = 0; mp < &m[MAXMALLOCS]; ++mp) {
  312.         if (mp->addr != NULL)
  313.             num++;
  314.     }
  315.     found = 0;
  316.     { /* windows */
  317.         register WINDOW *wp;
  318.         for (wp=wheadp; wp != NULL; wp = wp->w_wndp)
  319.             found++;
  320.     }
  321.     { /* buffers */
  322.         register BUFFER *bp;
  323.         for (bp=bheadp; bp != NULL; bp = bp->b_bufp) {
  324.             LINE *lp;
  325.             found++; /* for b_linep */
  326.             for(lp = bp->b_line.l; lp->l_fp != bp->b_line.l;
  327.                                 lp = lp->l_fp)
  328.                 found++;
  329.             if (bp->b_nmmarks)
  330.                 found++;
  331.             if (bp->b_ulinep)
  332.                 found++;
  333.             found++;  /* for the buffer itself */
  334.             for (i = 0; i < 2; i++) {
  335.                 for (lp = bp->b_udstks[i]; lp != NULL;
  336.                             lp = lp->l_nxtundo)
  337.                     found++;
  338.             }
  339.         }
  340.     }
  341.     found += term.t_mrow+1;  /* vscreen and the rows */
  342. #if ! MEMMAP
  343.     found += term.t_mrow+1;  /* pscreen and the rows */
  344. #endif
  345.     if (fline)
  346.         found++;
  347. #if ! SMALLER && LATER
  348.     { /* user vars */
  349.         extern UVAR uv[MAXVARS];
  350.         for (i=0; i < MAXVARS; i++)
  351.             if (uv[i].u_value) found++;
  352.     }
  353. #endif
  354. #if    FILOCK
  355.     need to count lock mallocs...
  356. #endif
  357.     { /* searching */
  358.         register MC    *mcptr;
  359.  
  360.         if (patmatch)
  361.             found++;
  362.             
  363.         mcptr = &mcpat[0];
  364.         while (mcptr->mc_type != MCNIL)
  365.         {
  366.             if ((mcptr->mc_type & MASKCL) == CCL ||
  367.                 (mcptr->mc_type & MASKCL) == NCCL)
  368.                 if (mcptr->u.cclmap) found++;
  369.             mcptr++;
  370.         }
  371.     }
  372.     { /* kill registers */
  373.         for (i = 0; i < NKREGS; i++) {
  374.             KILL *kb;
  375.             if ((kb = kbs[i].kbufh) != NULL) {
  376.                 while (kb) {
  377.                     found++;
  378.                     kb = kb->d_next;
  379.                 }
  380.             }
  381.         }
  382.     }
  383.     mlforce("doverifys %s %d, outstanding mallocs: %d, %d accounted for.",
  384.         f ? "set to":"is still", doverifys, num, found);
  385. #else
  386.     mlforce("doverifys %s %d",
  387.         f ? "set to":"is still", doverifys);
  388. #endif
  389.     return TRUE;
  390. }
  391.  
  392. #endif
  393.