home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
-
- /* #define MEM_NORMAL 1 */
-
- #include "global.h"
- #include "cmdparse.h"
- #include "mem.h"
- #include "misc.h"
-
- static int Memory_Debug = 0;
-
- static struct Allocation_Struct
- {
- char *Data;
- unsigned int Size;
- int Type;
- char *File;
- int Line;
- time_t Time;
- struct Allocation_Struct *Next;
- }
- *Allocation_Start = (struct Allocation_Struct *)NULL;
-
- static int Allocation_Audit(struct Allocation_Struct *);
-
- static int doaudit(int, char **);
- static int dodebug(int, char **);
- static int dodump(int, char **);
- static int dolist(int, char **);
- static int dostats(int, char **);
-
- static struct cmds Mcmds[] = {
- "audit", doaudit, 0, NULLCHAR, NULLCHAR,
- "debug", dodebug, 0, NULLCHAR, NULLCHAR,
- "dump", dodump, 0, NULLCHAR, NULLCHAR,
- "list", dolist, 0, NULLCHAR, NULLCHAR,
- "stats", dostats, 0, NULLCHAR, NULLCHAR,
- NULLCHAR, NULLFP, 0, "mem subcommands: audit debug dump list stats", NULLCHAR
- };
-
- int domem(int argc, char **argv)
- {
- return subcmd(Mcmds, argc, argv);
- }
-
- static int dodebug(int argc, char **argv)
- {
- if (argc == 1)
- cwprintf(NULL, "memory debugging %s\r\n", (Memory_Debug) ? "on" : "off");
- else
- {
- if (strcmp(argv[1], "on") == 0)
- Memory_Debug = 1;
- else
- Memory_Debug = 0;
- }
-
- return 0;
- }
-
- static int dolist(int argc, char **argv)
- {
- struct Allocation_Struct *Allocation_Ptr;
- time_t Time_Now;
- char *Type;
-
- argc = argc;
- argv = argv;
-
- Time_Now = time(NULL);
-
- Allocation_Ptr = Allocation_Start;
-
- cwprintf(NULL, "Address Size Type File Line Age\r\n");
-
- while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
- {
- switch (Allocation_Ptr->Type)
- {
- case 'c':
- Type = "calloc";
- break;
- case 'm':
- Type = "malloc";
- break;
- case 's':
- Type = "strdup";
- break;
- default:
- Type = "???";
- break;
- }
-
- cwprintf(NULL, "%06X %5u %-6s %-10s %4d %5u\r\n",
- Allocation_Ptr->Data + 4, Allocation_Ptr->Size,
- Type, Allocation_Ptr->File, Allocation_Ptr->Line,
- Time_Now - Allocation_Ptr->Time);
-
- /*
- cwprintf(NULL, "%06X %5u %-6s %-10s %4d %.0f\r\n",
- Allocation_Ptr->Data + 4, Allocation_Ptr->Size,
- Type, Allocation_Ptr->File,
- Allocation_Ptr->Line, difftime(Time_Now, Allocation_Ptr->Time));
- */
-
- Allocation_Ptr = Allocation_Ptr->Next;
- }
-
- return(0);
- }
-
- static int doaudit(int argc, char **argv)
- {
- register struct Allocation_Struct *Allocation_Ptr;
- int Error = 0;
-
- argc = argc;
- argv = argv;
-
- Allocation_Ptr = Allocation_Start;
-
- while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
- {
- Error = Allocation_Audit(Allocation_Ptr);
-
- Allocation_Ptr = Allocation_Ptr->Next;
- }
-
- if (!Error) cwprintf(NULL, "memory audit successful - no memory errors\r\n");
-
- return(0);
- }
-
- static int Allocation_Audit(register struct Allocation_Struct *Allocation_Ptr)
- {
- char *Type;
- int Error = 0;
-
- switch (Allocation_Ptr->Type)
- {
- case 'c':
- Type = "calloc";
- break;
- case 'm':
- Type = "malloc";
- break;
- case 's':
- Type = "strdup";
- break;
- default:
- Type = "???";
- break;
- }
-
- if (Allocation_Ptr->Data[0] != 0xAA ||
- Allocation_Ptr->Data[1] != 0x55 ||
- Allocation_Ptr->Data[2] != 0xAA ||
- Allocation_Ptr->Data[3] != 0x55)
- {
- cwprintf(NULL, "memory error: data underrun at %06X %s'd in %s at line %d\r\n",
- Allocation_Ptr->Data + 4, Type, Allocation_Ptr->File, Allocation_Ptr->Line);
- Error = 1;
- }
-
- if (Allocation_Ptr->Data[Allocation_Ptr->Size + 4] != 0xAA ||
- Allocation_Ptr->Data[Allocation_Ptr->Size + 5] != 0x55 ||
- Allocation_Ptr->Data[Allocation_Ptr->Size + 6] != 0xAA ||
- Allocation_Ptr->Data[Allocation_Ptr->Size + 7] != 0x55)
- {
- cwprintf(NULL, "memory error: data overrun at %06X %s'd in %s at line %d\r\n",
- Allocation_Ptr->Data + 4, Type, Allocation_Ptr->File, Allocation_Ptr->Line);
- Error = 1;
- }
-
- return(Error);
- }
-
- static int dodump(int argc, char **argv)
- {
- static char *Address = (char *)0x8000;
- char *p;
-
- if (argc > 1) Address = (char *)htoi(argv[1]);
-
- for (p = Address; p < Address + 80; p += 16)
- {
- cwprintf(NULL, "%06X: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ",
- p, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
- p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
-
- cwprintf(NULL, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\r\n",
- (isalnum(p[0])) ? p[0] : '.', (isalnum(p[1])) ? p[1] : '.',
- (isalnum(p[2])) ? p[2] : '.', (isalnum(p[3])) ? p[3] : '.',
- (isalnum(p[4])) ? p[4] : '.', (isalnum(p[5])) ? p[5] : '.',
- (isalnum(p[6])) ? p[6] : '.', (isalnum(p[7])) ? p[7] : '.',
- (isalnum(p[8])) ? p[8] : '.', (isalnum(p[9])) ? p[9] : '.',
- (isalnum(p[10])) ? p[10] : '.', (isalnum(p[11])) ? p[11] : '.',
- (isalnum(p[12])) ? p[12] : '.', (isalnum(p[13])) ? p[13] : '.',
- (isalnum(p[14])) ? p[14] : '.', (isalnum(p[15])) ? p[15] : '.');
- }
-
- Address += 80;
-
- return(0);
- }
-
- static int dostats(int argc, char **argv)
- {
- register struct Allocation_Struct *Allocation_Ptr;
- int Malloc_Count = 0;
- int Malloc_Size = 0;
- int Calloc_Count = 0;
- int Calloc_Size = 0;
- int Strdup_Count = 0;
- int Strdup_Size = 0;
-
- argc = argc;
- argv = argv;
-
- Allocation_Ptr = Allocation_Start;
-
- while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
- {
- switch (Allocation_Ptr->Type)
- {
- case 'c':
- Calloc_Size += Allocation_Ptr->Size;
- Calloc_Count++;
- break;
- case 'm':
- Malloc_Size += Allocation_Ptr->Size;
- Malloc_Count++;
- break;
- case 's':
- Strdup_Size += Allocation_Ptr->Size;
- Strdup_Count++;
- break;
- default:
- cwprintf(NULL, "Unknown allocation type %c\r\n", Allocation_Ptr->Type);
- break;
- }
-
- Allocation_Ptr = Allocation_Ptr->Next;
- }
-
- cwprintf(NULL, "calloc: calls:%d bytes:%d\r\n", Calloc_Count, Calloc_Size);
- cwprintf(NULL, "malloc: calls:%d bytes:%d\r\n", Malloc_Count, Malloc_Size);
- cwprintf(NULL, "strdup: calls:%d bytes:%d\r\n", Strdup_Count, Strdup_Size);
-
- return(0);
- }
-
- void *mem_malloc(unsigned int Size, char *File, int Line)
- {
- register struct Allocation_Struct *Allocation_Ptr;
- register struct Allocation_Struct *Last_Allocation;
-
- if (Memory_Debug) cwprintf(NULL, "memory: malloc of %u bytes in %s at line %d\r\n", Size, File, Line);
-
- if (Size < 1)
- {
- cwprintf(NULL, "memory error: tryed to malloc an area less than one byte in %s at line %d\r\n", File, Line);
- return(NULL);
- }
-
- if ((Allocation_Ptr = malloc(sizeof(struct Allocation_Struct))) == (struct Allocation_Struct *)NULL)
- {
- cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
- return(NULL);
- }
-
- if ((Allocation_Ptr->Data = malloc(Size + 8)) == NULL)
- {
- cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
- free(Allocation_Ptr);
- return(NULL);
- }
-
- Allocation_Ptr->Size = Size;
- Allocation_Ptr->File = File;
- Allocation_Ptr->Line = Line;
- Allocation_Ptr->Type = 'm';
- Allocation_Ptr->Time = time(NULL);
- Allocation_Ptr->Next = (struct Allocation_Struct *)NULL;
-
- if (Allocation_Start == (struct Allocation_Struct *)NULL)
- {
- Allocation_Start = Allocation_Ptr;
- }
- else
- {
- Last_Allocation = Allocation_Start;
-
- while (Last_Allocation->Next != (struct Allocation_Struct *)NULL)
- Last_Allocation = Last_Allocation->Next;
-
- Last_Allocation->Next = Allocation_Ptr;
- }
-
- Allocation_Ptr->Data[0] = 0xAA;
- Allocation_Ptr->Data[1] = 0x55;
- Allocation_Ptr->Data[2] = 0xAA;
- Allocation_Ptr->Data[3] = 0x55;
-
- Allocation_Ptr->Data[Size + 4] = 0xAA;
- Allocation_Ptr->Data[Size + 5] = 0x55;
- Allocation_Ptr->Data[Size + 6] = 0xAA;
- Allocation_Ptr->Data[Size + 7] = 0x55;
-
- /* malloc() isn't defined to guarantee that the area is clear, but I do */
- memset(Allocation_Ptr->Data + 4, 0, Size);
-
- if (Memory_Debug) cwprintf(NULL, " Allocated at %06X\r\n", Allocation_Ptr->Data + 4);
-
- return(Allocation_Ptr->Data + 4);
- }
-
- void *mem_calloc(unsigned int Number, unsigned int Size, char *File, int Line)
- {
- register struct Allocation_Struct *Allocation_Ptr;
- register struct Allocation_Struct *Last_Allocation;
- unsigned int Total;
-
- Total = Number * Size;
-
- if (Memory_Debug) cwprintf(NULL, "memory: calloc of %u bytes in %s at line %d\r\n", Total, File, Line);
-
- if (Total < 1)
- {
- cwprintf(NULL, "memory error: tryed to calloc an area less than one byte in %s at line %d\r\n", File, Line);
- return(NULL);
- }
-
- if ((Allocation_Ptr = malloc(sizeof(struct Allocation_Struct))) == (struct Allocation_Struct *)NULL)
- {
- cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
- return(NULL);
- }
-
- if ((Allocation_Ptr->Data = malloc(Total + 8)) == NULL)
- {
- cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
- free(Allocation_Ptr);
- return(NULL);
- }
-
- Allocation_Ptr->Size = Total;
- Allocation_Ptr->File = File;
- Allocation_Ptr->Line = Line;
- Allocation_Ptr->Type = 'c';
- Allocation_Ptr->Time = time(NULL);
- Allocation_Ptr->Next = (struct Allocation_Struct *)NULL;
-
- if (Allocation_Start == (struct Allocation_Struct *)NULL)
- {
- Allocation_Start = Allocation_Ptr;
- }
- else
- {
- Last_Allocation = Allocation_Start;
-
- while (Last_Allocation->Next != (struct Allocation_Struct *)NULL)
- Last_Allocation = Last_Allocation->Next;
-
- Last_Allocation->Next = Allocation_Ptr;
- }
-
- Allocation_Ptr->Data[0] = 0xAA;
- Allocation_Ptr->Data[1] = 0x55;
- Allocation_Ptr->Data[2] = 0xAA;
- Allocation_Ptr->Data[3] = 0x55;
-
- Allocation_Ptr->Data[Total + 4] = 0xAA;
- Allocation_Ptr->Data[Total + 5] = 0x55;
- Allocation_Ptr->Data[Total + 6] = 0xAA;
- Allocation_Ptr->Data[Total + 7] = 0x55;
-
- /* calloc() is defined to clear the allocated area */
- memset(Allocation_Ptr->Data + 4, 0, Total);
-
- if (Memory_Debug) cwprintf(NULL, " Allocated at %06X\r\n", Allocation_Ptr->Data + 4);
-
- return(Allocation_Ptr->Data + 4);
- }
-
- char *mem_strdup(char *String, char *File, int Line)
- {
- register struct Allocation_Struct *Allocation_Ptr;
- register struct Allocation_Struct *Last_Allocation;
- int Size;
-
- Size = strlen(String) + 1;
-
- if (Memory_Debug) cwprintf(NULL, "memory: strdup of \"%s\" in %s at line %d\r\n", String, File, Line);
-
- if (String == NULLCHAR)
- {
- cwprintf(NULL, "memory error: tryed to strdup a NULL pointer in %s at line %d\r\n", File, Line);
- return(NULL);
- }
-
- if ((Allocation_Ptr = malloc(sizeof(struct Allocation_Struct))) == (struct Allocation_Struct *)NULL)
- {
- cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
- return(NULL);
- }
-
- if ((Allocation_Ptr->Data = malloc(Size + 8)) == NULL)
- {
- cwprintf(NULL, "memory error: out of memory in %s at line %d\r\n", File, Line);
- free(Allocation_Ptr);
- return(NULL);
- }
-
- Allocation_Ptr->Size = Size;
- Allocation_Ptr->File = File;
- Allocation_Ptr->Line = Line;
- Allocation_Ptr->Type = 's';
- Allocation_Ptr->Time = time(NULL);
- Allocation_Ptr->Next = (struct Allocation_Struct *)NULL;
-
- if (Allocation_Start == (struct Allocation_Struct *)NULL)
- {
- Allocation_Start = Allocation_Ptr;
- }
- else
- {
- Last_Allocation = Allocation_Start;
-
- while (Last_Allocation->Next != (struct Allocation_Struct *)NULL)
- Last_Allocation = Last_Allocation->Next;
-
- Last_Allocation->Next = Allocation_Ptr;
- }
-
- Allocation_Ptr->Data[0] = 0xAA;
- Allocation_Ptr->Data[1] = 0x55;
- Allocation_Ptr->Data[2] = 0xAA;
- Allocation_Ptr->Data[3] = 0x55;
-
- Allocation_Ptr->Data[Size + 4] = 0xAA;
- Allocation_Ptr->Data[Size + 5] = 0x55;
- Allocation_Ptr->Data[Size + 6] = 0xAA;
- Allocation_Ptr->Data[Size + 7] = 0x55;
-
- strcpy(Allocation_Ptr->Data + 4, String);
-
- if (Memory_Debug) cwprintf(NULL, " Allocated at %06X\r\n", Allocation_Ptr->Data + 4);
-
- return(Allocation_Ptr->Data + 4);
- }
-
- char *strdup(char *String)
- {
- char *s;
-
- if (String == NULLCHAR) return(NULLCHAR);
-
- if ((s = malloc(strlen(String) + 1)) == NULL)
- {
- cwprintf(NULL, "memory error: out of memory in MEM\r\n");
- return(NULLCHAR);
- }
-
- strcpy(s, String);
-
- return(s);
- }
-
- void mem_free(void *Address, char *File, int Line)
- {
- register struct Allocation_Struct *Allocation_Ptr;
- register struct Allocation_Struct *Last_Allocation;
-
- if (Memory_Debug) cwprintf(NULL, "memory: freeing pointer %06X in %s at line %d\r\n", Address, File, Line);
-
- if (Address == NULL)
- {
- cwprintf(NULL, "memory error: attempting to free NULL pointer in %s at line %d\r\n", File, Line);
- return;
- }
-
- if ((Allocation_Ptr = Allocation_Start) != (struct Allocation_Struct *)NULL)
- {
- if (Address == Allocation_Ptr->Data + 4)
- {
- Allocation_Start = Allocation_Ptr->Next;
- if (Allocation_Audit(Allocation_Ptr))
- cwprintf(NULL, "memory error: Free'd in %s at line %d\r\n", File, Line);
- free(Allocation_Ptr->Data);
- free(Allocation_Ptr);
- return;
- }
-
- Last_Allocation = Allocation_Ptr;
- Allocation_Ptr = Allocation_Ptr->Next;
- }
-
- while (Allocation_Ptr != (struct Allocation_Struct *)NULL)
- {
- if (Address == Allocation_Ptr->Data + 4)
- {
- Last_Allocation->Next = Allocation_Ptr->Next;
- if (Allocation_Audit(Allocation_Ptr))
- cwprintf(NULL, "memory error: Free'd in %s at line %d\r\n", File, Line);
- free(Allocation_Ptr->Data);
- free(Allocation_Ptr);
- return;
- }
-
- Last_Allocation = Allocation_Ptr;
- Allocation_Ptr = Allocation_Ptr->Next;
- }
-
- cwprintf(NULL, "memory error: attempted to free unknown pointer %06X in %s at line %d\r\n", Address, File, Line);
- }
-
-