home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / h / if / Misc / c / mem < prev    next >
Encoding:
Text File  |  1994-06-24  |  17.1 KB  |  522 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6.  
  7. /* #define MEM_NORMAL      1 */
  8.  
  9. #include "global.h"
  10. #include "cmdparse.h"
  11. #include "mem.h"
  12. #include "misc.h"
  13.  
  14. static int Memory_Debug = 0;
  15.  
  16. static struct Allocation_Struct
  17. {
  18.         char *Data;
  19.         unsigned int Size;
  20.         int  Type;
  21.         char *File;
  22.         int  Line;
  23.         time_t Time;
  24.         struct Allocation_Struct *Next;
  25. }
  26. *Allocation_Start = (struct Allocation_Struct *)NULL;
  27.  
  28. static int Allocation_Audit(struct Allocation_Struct *);
  29.  
  30. static int doaudit(int, char **);
  31. static int dodebug(int, char **);
  32. static int dodump(int, char **);
  33. static int dolist(int, char **);
  34. static int dostats(int, char **);
  35.  
  36. static struct cmds Mcmds[] = {
  37.         "audit",        doaudit,        0, NULLCHAR, NULLCHAR,
  38.         "debug",        dodebug,        0, NULLCHAR, NULLCHAR,
  39.         "dump",         dodump,         0, NULLCHAR, NULLCHAR,
  40.         "list",         dolist,         0, NULLCHAR, NULLCHAR,
  41.         "stats",        dostats,        0, NULLCHAR, NULLCHAR,
  42.         NULLCHAR,       NULLFP,         0, "mem subcommands: audit debug dump list stats", NULLCHAR
  43. };
  44.  
  45. int domem(int argc, char **argv)
  46. {
  47.         return subcmd(Mcmds, argc, argv);    
  48. }
  49.  
  50. static int dodebug(int argc, char **argv)
  51. {
  52.         if (argc == 1)
  53.                 cwprintf(NULL, "memory debugging %s\r\n", (Memory_Debug) ? "on" : "off");
  54.         else
  55.         {
  56.                 if (strcmp(argv[1], "on") == 0)
  57.                         Memory_Debug = 1;
  58.                 else
  59.                         Memory_Debug = 0;
  60.         }
  61.  
  62.         return 0;
  63. }
  64.  
  65. static int dolist(int argc, char **argv)
  66. {
  67.         struct Allocation_Struct *Allocation_Ptr;
  68.         time_t Time_Now;
  69.         char *Type;
  70.  
  71.         argc = argc;
  72.         argv = argv;
  73.  
  74.         Time_Now = time(NULL);
  75.  
  76.         Allocation_Ptr = Allocation_Start;
  77.  
  78.         cwprintf(NULL, "Address  Size   Type    File        Line   Age\r\n");
  79.  
  80.         while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
  81.         {
  82.                 switch (Allocation_Ptr->Type)
  83.                 {
  84.                         case 'c':
  85.                                 Type = "calloc";
  86.                                 break;
  87.                         case 'm':
  88.                                 Type = "malloc";
  89.                                 break;
  90.                         case 's':
  91.                                 Type = "strdup";
  92.                                 break;
  93.                         default:
  94.                                 Type = "???";
  95.                                 break;
  96.                 }
  97.  
  98.                 cwprintf(NULL, "%06X  %5u  %-6s  %-10s  %4d  %5u\r\n",
  99.                         Allocation_Ptr->Data + 4, Allocation_Ptr->Size,
  100.                         Type, Allocation_Ptr->File, Allocation_Ptr->Line,
  101.                         Time_Now - Allocation_Ptr->Time);
  102.  
  103. /*
  104.                 cwprintf(NULL, "%06X  %5u  %-6s  %-10s  %4d  %.0f\r\n",
  105.                         Allocation_Ptr->Data + 4, Allocation_Ptr->Size,
  106.                         Type, Allocation_Ptr->File,
  107.                         Allocation_Ptr->Line, difftime(Time_Now, Allocation_Ptr->Time));
  108. */
  109.  
  110.                 Allocation_Ptr = Allocation_Ptr->Next;
  111.         }
  112.  
  113.         return(0);
  114. }
  115.  
  116. static int doaudit(int argc, char **argv)
  117. {
  118.         register struct Allocation_Struct *Allocation_Ptr;
  119.         int Error = 0;
  120.  
  121.         argc = argc;
  122.         argv = argv;
  123.  
  124.         Allocation_Ptr = Allocation_Start;
  125.  
  126.         while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
  127.         {
  128.                 Error = Allocation_Audit(Allocation_Ptr);
  129.  
  130.                 Allocation_Ptr = Allocation_Ptr->Next;
  131.         }
  132.  
  133.         if (!Error) cwprintf(NULL, "memory audit successful - no memory errors\r\n");
  134.  
  135.         return(0);
  136. }
  137.  
  138. static int Allocation_Audit(register struct Allocation_Struct *Allocation_Ptr)
  139. {
  140.         char *Type;
  141.         int Error = 0;
  142.  
  143.         switch (Allocation_Ptr->Type)
  144.         {
  145.                 case 'c':
  146.                         Type = "calloc";
  147.                         break;
  148.                 case 'm':
  149.                         Type = "malloc";
  150.                         break;
  151.                 case 's':
  152.                         Type = "strdup";
  153.                         break;
  154.                 default:
  155.                         Type = "???";
  156.                         break;
  157.         }
  158.  
  159.         if (Allocation_Ptr->Data[0] != 0xAA ||
  160.             Allocation_Ptr->Data[1] != 0x55 ||
  161.             Allocation_Ptr->Data[2] != 0xAA ||
  162.             Allocation_Ptr->Data[3] != 0x55)
  163.         {
  164.                 cwprintf(NULL, "memory error: data underrun at %06X %s'd in %s at line %d\r\n",
  165.                         Allocation_Ptr->Data + 4, Type, Allocation_Ptr->File, Allocation_Ptr->Line);
  166.                 Error = 1;
  167.         }
  168.  
  169.         if (Allocation_Ptr->Data[Allocation_Ptr->Size + 4] != 0xAA ||
  170.             Allocation_Ptr->Data[Allocation_Ptr->Size + 5] != 0x55 ||
  171.             Allocation_Ptr->Data[Allocation_Ptr->Size + 6] != 0xAA ||
  172.             Allocation_Ptr->Data[Allocation_Ptr->Size + 7] != 0x55)
  173.         {
  174.                 cwprintf(NULL, "memory error: data overrun at %06X %s'd in %s at line %d\r\n",
  175.                         Allocation_Ptr->Data + 4, Type, Allocation_Ptr->File, Allocation_Ptr->Line);
  176.                 Error = 1;
  177.         }
  178.  
  179.         return(Error);
  180. }
  181.  
  182. static int dodump(int argc, char **argv)
  183. {
  184.         static char *Address = (char *)0x8000;
  185.         char *p;
  186.  
  187.         if (argc > 1) Address = (char *)htoi(argv[1]);
  188.  
  189.         for (p = Address; p < Address + 80; p += 16)
  190.         {
  191.                 cwprintf(NULL, "%06X: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X   ",
  192.                         p, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
  193.                         p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
  194.  
  195.                 cwprintf(NULL, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\r\n",
  196.                         (isalnum(p[0])) ? p[0] : '.',   (isalnum(p[1])) ? p[1] : '.',
  197.                         (isalnum(p[2])) ? p[2] : '.',   (isalnum(p[3])) ? p[3] : '.',
  198.                         (isalnum(p[4])) ? p[4] : '.',   (isalnum(p[5])) ? p[5] : '.',
  199.                         (isalnum(p[6])) ? p[6] : '.',   (isalnum(p[7])) ? p[7] : '.',
  200.                         (isalnum(p[8])) ? p[8] : '.',   (isalnum(p[9])) ? p[9] : '.',
  201.                         (isalnum(p[10])) ? p[10] : '.', (isalnum(p[11])) ? p[11] : '.',
  202.                         (isalnum(p[12])) ? p[12] : '.', (isalnum(p[13])) ? p[13] : '.',
  203.                         (isalnum(p[14])) ? p[14] : '.', (isalnum(p[15])) ? p[15] : '.');
  204.         }
  205.  
  206.         Address += 80;
  207.  
  208.         return(0);
  209. }
  210.  
  211. static int dostats(int argc, char **argv)
  212. {
  213.         register struct Allocation_Struct *Allocation_Ptr;
  214.         int Malloc_Count = 0;
  215.         int Malloc_Size  = 0;
  216.         int Calloc_Count = 0;
  217.         int Calloc_Size  = 0;
  218.         int Strdup_Count = 0;
  219.         int Strdup_Size  = 0;
  220.  
  221.         argc = argc;
  222.         argv = argv;
  223.  
  224.         Allocation_Ptr = Allocation_Start;
  225.  
  226.         while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
  227.         {
  228.                 switch (Allocation_Ptr->Type)
  229.                 {
  230.                         case 'c':
  231.                                 Calloc_Size += Allocation_Ptr->Size;
  232.                                 Calloc_Count++;
  233.                                 break;
  234.                         case 'm':
  235.                                 Malloc_Size += Allocation_Ptr->Size;
  236.                                 Malloc_Count++;
  237.                                 break;
  238.                         case 's':
  239.                                 Strdup_Size += Allocation_Ptr->Size;
  240.                                 Strdup_Count++;
  241.                                 break;
  242.                         default:
  243.                                 cwprintf(NULL, "Unknown allocation type %c\r\n", Allocation_Ptr->Type);
  244.                                 break;
  245.                 }
  246.  
  247.                 Allocation_Ptr = Allocation_Ptr->Next;
  248.         }
  249.  
  250.         cwprintf(NULL, "calloc: calls:%d bytes:%d\r\n", Calloc_Count, Calloc_Size);
  251.         cwprintf(NULL, "malloc: calls:%d bytes:%d\r\n", Malloc_Count, Malloc_Size);
  252.         cwprintf(NULL, "strdup: calls:%d bytes:%d\r\n", Strdup_Count, Strdup_Size);
  253.  
  254.         return(0);
  255. }
  256.  
  257. void *mem_malloc(unsigned int Size, char *File, int Line)
  258. {
  259.         register struct Allocation_Struct *Allocation_Ptr;
  260.         register struct Allocation_Struct *Last_Allocation;
  261.  
  262.         if (Memory_Debug) cwprintf(NULL, "memory: malloc of %u bytes in %s at line %d\r\n", Size, File, Line);
  263.  
  264.         if (Size < 1)
  265.         {
  266.                 cwprintf(NULL, "memory error: tryed to malloc an area less than one byte in %s at line %d\r\n", File, Line);
  267.                 return(NULL);
  268.         }
  269.  
  270.         if ((Allocation_Ptr = malloc(sizeof(struct Allocation_Struct))) == (struct Allocation_Struct *)NULL)
  271.         {
  272.                 cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
  273.                 return(NULL);
  274.         }
  275.  
  276.         if ((Allocation_Ptr->Data = malloc(Size + 8)) == NULL)
  277.         {
  278.                 cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
  279.                 free(Allocation_Ptr);
  280.                 return(NULL);
  281.         }
  282.  
  283.         Allocation_Ptr->Size = Size;
  284.         Allocation_Ptr->File = File;
  285.         Allocation_Ptr->Line = Line;
  286.         Allocation_Ptr->Type = 'm';
  287.         Allocation_Ptr->Time = time(NULL);
  288.         Allocation_Ptr->Next = (struct Allocation_Struct *)NULL;
  289.  
  290.         if (Allocation_Start == (struct Allocation_Struct *)NULL)
  291.         {
  292.                 Allocation_Start = Allocation_Ptr;
  293.         }
  294.         else
  295.         {
  296.                 Last_Allocation = Allocation_Start;
  297.  
  298.                 while (Last_Allocation->Next != (struct Allocation_Struct *)NULL)
  299.                         Last_Allocation = Last_Allocation->Next;
  300.  
  301.                 Last_Allocation->Next = Allocation_Ptr;
  302.         }
  303.  
  304.         Allocation_Ptr->Data[0] = 0xAA;
  305.         Allocation_Ptr->Data[1] = 0x55;
  306.         Allocation_Ptr->Data[2] = 0xAA;
  307.         Allocation_Ptr->Data[3] = 0x55;
  308.  
  309.         Allocation_Ptr->Data[Size + 4] = 0xAA;
  310.         Allocation_Ptr->Data[Size + 5] = 0x55;
  311.         Allocation_Ptr->Data[Size + 6] = 0xAA;
  312.         Allocation_Ptr->Data[Size + 7] = 0x55;
  313.  
  314.         /* malloc() isn't defined to guarantee that the area is clear, but I do */
  315.         memset(Allocation_Ptr->Data + 4, 0, Size);
  316.  
  317.         if (Memory_Debug) cwprintf(NULL, "        Allocated at %06X\r\n", Allocation_Ptr->Data + 4);
  318.  
  319.         return(Allocation_Ptr->Data + 4);
  320. }
  321.  
  322. void *mem_calloc(unsigned int Number, unsigned int Size, char *File, int Line)
  323. {
  324.         register struct Allocation_Struct *Allocation_Ptr;
  325.         register struct Allocation_Struct *Last_Allocation;
  326.         unsigned int Total;
  327.  
  328.         Total = Number * Size;
  329.  
  330.         if (Memory_Debug) cwprintf(NULL, "memory: calloc of %u bytes in %s at line %d\r\n", Total, File, Line);
  331.  
  332.         if (Total < 1)
  333.         {
  334.                 cwprintf(NULL, "memory error: tryed to calloc an area less than one byte in %s at line %d\r\n", File, Line);
  335.                 return(NULL);
  336.         }
  337.  
  338.         if ((Allocation_Ptr = malloc(sizeof(struct Allocation_Struct))) == (struct Allocation_Struct *)NULL)
  339.         {
  340.                 cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
  341.                 return(NULL);
  342.         }
  343.  
  344.         if ((Allocation_Ptr->Data = malloc(Total + 8)) == NULL)
  345.         {
  346.                 cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
  347.                 free(Allocation_Ptr);
  348.                 return(NULL);
  349.         }
  350.  
  351.         Allocation_Ptr->Size = Total;
  352.         Allocation_Ptr->File = File;
  353.         Allocation_Ptr->Line = Line;
  354.         Allocation_Ptr->Type = 'c';
  355.         Allocation_Ptr->Time = time(NULL);
  356.         Allocation_Ptr->Next = (struct Allocation_Struct *)NULL;
  357.  
  358.         if (Allocation_Start == (struct Allocation_Struct *)NULL)
  359.         {
  360.                 Allocation_Start = Allocation_Ptr;
  361.         }
  362.         else
  363.         {
  364.                 Last_Allocation = Allocation_Start;
  365.  
  366.                 while (Last_Allocation->Next != (struct Allocation_Struct *)NULL)
  367.                         Last_Allocation = Last_Allocation->Next;
  368.  
  369.                 Last_Allocation->Next = Allocation_Ptr;
  370.         }
  371.  
  372.         Allocation_Ptr->Data[0] = 0xAA;
  373.         Allocation_Ptr->Data[1] = 0x55;
  374.         Allocation_Ptr->Data[2] = 0xAA;
  375.         Allocation_Ptr->Data[3] = 0x55;
  376.  
  377.         Allocation_Ptr->Data[Total + 4] = 0xAA;
  378.         Allocation_Ptr->Data[Total + 5] = 0x55;
  379.         Allocation_Ptr->Data[Total + 6] = 0xAA;
  380.         Allocation_Ptr->Data[Total + 7] = 0x55;
  381.  
  382.         /* calloc() is defined to clear the allocated area */
  383.         memset(Allocation_Ptr->Data + 4, 0, Total);
  384.  
  385.         if (Memory_Debug) cwprintf(NULL, "        Allocated at %06X\r\n", Allocation_Ptr->Data + 4);
  386.  
  387.         return(Allocation_Ptr->Data + 4);
  388. }
  389.  
  390. char *mem_strdup(char *String, char *File, int Line)
  391. {
  392.         register struct Allocation_Struct *Allocation_Ptr;
  393.         register struct Allocation_Struct *Last_Allocation;
  394.         int Size;
  395.  
  396.         Size = strlen(String) + 1;
  397.  
  398.         if (Memory_Debug) cwprintf(NULL, "memory: strdup of \"%s\" in %s at line %d\r\n", String, File, Line);
  399.  
  400.         if (String == NULLCHAR)
  401.         {
  402.                 cwprintf(NULL, "memory error: tryed to strdup a NULL pointer in %s at line %d\r\n", File, Line);
  403.                 return(NULL);
  404.         }
  405.  
  406.         if ((Allocation_Ptr = malloc(sizeof(struct Allocation_Struct))) == (struct Allocation_Struct *)NULL)
  407.         {
  408.                 cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
  409.                 return(NULL);
  410.         }
  411.  
  412.         if ((Allocation_Ptr->Data = malloc(Size + 8)) == NULL)
  413.         {
  414.                 cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
  415.                 free(Allocation_Ptr);
  416.                 return(NULL);
  417.         }
  418.  
  419.         Allocation_Ptr->Size = Size;
  420.         Allocation_Ptr->File = File;
  421.         Allocation_Ptr->Line = Line;
  422.         Allocation_Ptr->Type = 's';
  423.         Allocation_Ptr->Time = time(NULL);
  424.         Allocation_Ptr->Next = (struct Allocation_Struct *)NULL;
  425.  
  426.         if (Allocation_Start == (struct Allocation_Struct *)NULL)
  427.         {
  428.                 Allocation_Start = Allocation_Ptr;
  429.         }
  430.         else
  431.         {
  432.                 Last_Allocation = Allocation_Start;
  433.  
  434.                 while (Last_Allocation->Next != (struct Allocation_Struct *)NULL)
  435.                         Last_Allocation = Last_Allocation->Next;
  436.  
  437.                 Last_Allocation->Next = Allocation_Ptr;
  438.         }
  439.  
  440.         Allocation_Ptr->Data[0] = 0xAA;
  441.         Allocation_Ptr->Data[1] = 0x55;
  442.         Allocation_Ptr->Data[2] = 0xAA;
  443.         Allocation_Ptr->Data[3] = 0x55;
  444.  
  445.         Allocation_Ptr->Data[Size + 4] = 0xAA;
  446.         Allocation_Ptr->Data[Size + 5] = 0x55;
  447.         Allocation_Ptr->Data[Size + 6] = 0xAA;
  448.         Allocation_Ptr->Data[Size + 7] = 0x55;
  449.  
  450.         strcpy(Allocation_Ptr->Data + 4, String);
  451.  
  452.         if (Memory_Debug) cwprintf(NULL, "        Allocated at %06X\r\n", Allocation_Ptr->Data + 4);
  453.  
  454.         return(Allocation_Ptr->Data + 4);
  455. }
  456.  
  457. char *strdup(char *String)
  458. {
  459.         char *s;
  460.  
  461.         if (String == NULLCHAR) return(NULLCHAR);
  462.  
  463.         if ((s = malloc(strlen(String) + 1)) == NULL)
  464.         {
  465.                 cwprintf(NULL, "memory error: out of memory in MEM\r\n");
  466.                 return(NULLCHAR);
  467.         }
  468.  
  469.         strcpy(s, String);
  470.  
  471.         return(s);
  472. }
  473.  
  474. void mem_free(void *Address, char *File, int Line)
  475. {
  476.         register struct Allocation_Struct *Allocation_Ptr;
  477.         register struct Allocation_Struct *Last_Allocation;
  478.  
  479.         if (Memory_Debug) cwprintf(NULL, "memory: freeing pointer %06X in %s at line %d\r\n", Address, File, Line);
  480.  
  481.         if (Address == NULL)
  482.         {
  483.                 cwprintf(NULL, "memory error: attempting to free NULL pointer in %s at line %d\r\n", File, Line);
  484.                 return;
  485.         }
  486.  
  487.         if ((Allocation_Ptr = Allocation_Start) != (struct Allocation_Struct *)NULL)
  488.         {
  489.                 if (Address == Allocation_Ptr->Data + 4)
  490.                 {
  491.                         Allocation_Start = Allocation_Ptr->Next;
  492.                         if (Allocation_Audit(Allocation_Ptr))
  493.                                 cwprintf(NULL, "memory error: Free'd in %s at line %d\r\n", File, Line);
  494.                         free(Allocation_Ptr->Data);
  495.                         free(Allocation_Ptr);
  496.                         return;
  497.                 }
  498.  
  499.                 Last_Allocation = Allocation_Ptr;
  500.                 Allocation_Ptr  = Allocation_Ptr->Next;
  501.         }
  502.  
  503.         while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
  504.         {
  505.                 if (Address == Allocation_Ptr->Data + 4)
  506.                 {
  507.                         Last_Allocation->Next = Allocation_Ptr->Next;
  508.                         if (Allocation_Audit(Allocation_Ptr))
  509.                                 cwprintf(NULL, "memory error: Free'd in %s at line %d\r\n", File, Line);
  510.                         free(Allocation_Ptr->Data);
  511.                         free(Allocation_Ptr);
  512.                         return;
  513.                 }
  514.  
  515.                 Last_Allocation = Allocation_Ptr;
  516.                 Allocation_Ptr  = Allocation_Ptr->Next;
  517.         }
  518.  
  519.         cwprintf(NULL, "memory error: attempted to free unknown pointer %06X in %s at line %d\r\n", Address, File, Line);
  520. }
  521.  
  522.