home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 406_01 / disked25 / source / debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-13  |  6.0 KB  |  268 lines

  1. /***
  2. *debug.c - heap checking
  3. *
  4. *Copyright (c) 1993-1994, Gregg Jennings.  All wrongs reserved.
  5. *   P O Box 200, Falmouth, MA 02541-0200
  6. *
  7. *Purpose:
  8. *   Debugging support for DISKED.C.
  9. *
  10. *Notice:
  11. *   This progam may be freely used and distributed.  Any distrubution
  12. *   with modifications must retain the above copyright statement and
  13. *   modifications noted.
  14. *   No pulp-publication, in whole or in part, permitted without
  15. *   permission (magazines or books).
  16. *******************************************************************************/
  17.  
  18. /*
  19.    Versions
  20.  
  21.    2.1   13-Jan-1994    "alloc.h"
  22.    2.0   28-Nov-1993
  23. */
  24.  
  25. #include <stdio.h>
  26. #include <conio.h>
  27. #include <dos.h>
  28. #include <malloc.h>
  29.  
  30. #include "mylib.h"                        /* print and cursor routines */
  31. #include "alloc.h"
  32.  
  33. /*********** EXTERNAL DATA ***********/
  34.  
  35. extern unsigned int blocks;               /* alloc() free() calls */
  36. extern unsigned int nblocks;
  37. extern unsigned int frees;
  38. extern unsigned int nfrees;
  39.  
  40. extern char *heapstat(int status);
  41.  
  42. /********** INTERNAL DATA ***********/
  43.  
  44. static int list = 1;
  45. static char *list_types[]={"","ascii","byte","word","dword"};
  46.  
  47. static void list_memory(int type);
  48. void heapdump(int );
  49.  
  50. void debug(void)
  51. {
  52. int c;
  53.  
  54.    for (;;)
  55.    {
  56.       print("\n(debug)*");
  57.       c=conin()&0xff;
  58.       if (c=='h')
  59.       {
  60.          print(" Heap status:");
  61.          printf("\n\n\tStack available %u",stackavail());
  62. #ifdef _MSC_VER
  63.          printf(", near heap %u",_memavl());
  64.          printf(" (largest block %u).",_memmax());
  65. #endif
  66.          printf("\n\tAlloc calls %d:%d, Free calls %d:%d.",blocks,nblocks,frees,nfrees);
  67.          heapdump(0);
  68.       }
  69.       else if (c=='d')
  70.       {
  71.          print(" Heap dump:");
  72.          heapdump(1);
  73.       }
  74.       else if (c=='k')
  75.       {
  76.          list++;
  77.          if (list==5)
  78.             list=1;
  79.          printf(list_types[list]);
  80.          list_memory(list);
  81.       }
  82.       else if (c=='l')
  83.          list_memory(0);
  84.       else if (c=='.' || c==0x1b)
  85.          break;
  86.       else if (c=='/' || c=='?')
  87.       {
  88.          print(" Debug Commands:\n\n");
  89.          print("    'h' heap status\n");
  90.          print("    'd' heap dump\n");
  91.          print(" 'ln:n' list memory\n");
  92.          print("    'k' change list format\n");
  93.       }
  94.    }
  95. }
  96.  
  97. /*
  98.    display heap
  99.  
  100.    This is from the Microsoft online help database with slight
  101.    modifications.
  102. */
  103.  
  104. void heapdump(int stat)
  105. {
  106. struct _heapinfo hi;
  107. int heapstatus;
  108. register size_t i;
  109. register char _far *p;
  110. int uf,un,ff,fn;
  111.  
  112.    printf("\n");
  113.    uf = un = ff = fn = 0;
  114.    hi._pentry = NULL;
  115.    if (stat)
  116.       printf("\nFar Heap:");
  117.  
  118.    while ((heapstatus = _heapwalk( &hi )) == _HEAPOK)
  119.    {
  120.       if (stat)
  121.       printf( "\n\t%s block at %Fp of size %u\t",
  122.               hi._useflag == _USEDENTRY ? "USED" : "FREE",
  123.               hi._pentry,
  124.               hi._size );
  125.  
  126.       if (hi._useflag == _FREEENTRY)
  127.       {
  128.          ++ff;
  129.          if (stat)
  130.          for (p = (char _far *)hi._pentry, i = 0; i < hi._size; p++,i++)
  131.            if ((char)*p != (char)254)
  132.            {
  133.               printf(" overwrite at %Fp (%02X)",p,(char)*p);
  134.               break;
  135.            }
  136.       }
  137.       else
  138.          ++uf;
  139.    }
  140.    if (stat)
  141.       printf("\n\tStatus: %s",heapstat(heapstatus));
  142.  
  143.    hi._pentry = NULL;
  144.    if (stat)
  145.       printf("\nNear Heap:");
  146.    while ((heapstatus = _nheapwalk( &hi )) == _HEAPOK)
  147.    {
  148.       if (stat)
  149.       printf( "\n\t%s block at %Fp of size %u\t",
  150.               hi._useflag == _USEDENTRY ? "USED" : "FREE",
  151.               hi._pentry,
  152.               hi._size );
  153.  
  154.       if (hi._useflag == _FREEENTRY)
  155.       {
  156.          ++fn;
  157.          if (stat)
  158.          for (p = (char _far *)hi._pentry, i = 0; i < hi._size; p++,i++)
  159.             if ((char)*p != (char)254)
  160.             {
  161.                printf(" overwrite at %Fp (%02X)",p,(char)*p);
  162.                break;
  163.             }
  164.       }
  165.       else
  166.          ++un;
  167.    }
  168.    if (stat)
  169.       printf("\n\tStatus: %s\n",heapstat(heapstatus));
  170.    if (!stat)
  171.       printf("\tUsed blocks %d:%d, Free blocks %d:%d.\n",uf,un,ff,fn);
  172. }
  173.  
  174. #ifdef _MSC_VER
  175. #pragma check_pointer(off)
  176. #endif
  177.  
  178. /* dump memory, call with 0 to "set" format */
  179.  
  180. static void list_memory(int type)
  181. {
  182. int i,j;
  183. static byte  _far *cp;
  184. static word  _far *ip;
  185. static dword _far *lp;
  186. static int size = 1;
  187. char inbuf[20];
  188.  
  189.    if (type)
  190.    {
  191.       size=type;
  192.       return;
  193.    }
  194.    conout('l');
  195.    if ((i = getstr(inbuf,9,_PUNCT)) > 0)
  196.    {
  197.       i = j = 0;
  198.       sscanf(inbuf,"%x:%x",&i,&j);
  199.       cp = (byte _far *) ((((long)i)<<16) + (long)j);
  200.       ip = (word _far *) ((((long)i)<<16) + (long)j);
  201.       lp = (dword _far *) ((((long)i)<<16) + (long)j);
  202.    }
  203.    else if (i == ABORT)
  204.       return;
  205.    send('\n');
  206.    for (i=0;i<8;i++)
  207.    {
  208.       if (size==1)
  209.       {
  210.          printf("\n%Fp ",cp);
  211.          for (j=0;j<80-21;j++)
  212.          {
  213.             if (*cp == 0 || *cp == 255)
  214.                charout('.');
  215.             else
  216.                charout(*cp);
  217.             cp++;
  218.             curright();
  219.          }
  220.       }
  221.       else if (size==2)
  222.       {
  223.          printf("\n%Fp ",cp);
  224.          for (j=0;j<20;j++)
  225.          {
  226.             pnlz((int)*cp++,2,16);
  227.             curright();
  228.          }
  229.       }
  230.       else if (size==3)
  231.       {
  232.          printf("\n%Fp ",ip);
  233.          for (j=0;j<12;j++)
  234.          {
  235.             pnlz(*ip++,4,16);
  236.             curright();
  237.          }
  238.       }
  239.       else if (size==4)
  240.       {
  241.          printf("\n%Fp ",lp);
  242.          for (j=0;j<6;j++)
  243.          {
  244.             pnlz((int)((*lp)>>16),4,16);
  245.             conout(':');
  246.             pnlz((int)*lp++,4,16);
  247.             curright();
  248.          }
  249.       }
  250.    }
  251.    if (size == 1 || size == 2)
  252.    {
  253.       ip = (word _far *)cp;
  254.       lp = (dword _far *)cp;
  255.    }
  256.    else if (size == 3)
  257.    {
  258.       cp = (byte _far *)ip;
  259.       lp = (dword _far *)ip;
  260.    }
  261.    else if (size == 4)
  262.    {
  263.       ip = (word _far *)lp;
  264.       cp = (byte _far *)lp;
  265.    }
  266.    send('\n');
  267. }
  268.