home *** CD-ROM | disk | FTP | other *** search
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
- * |_o_o|\\ Copyright (c) 1989 The Software Distillery. *
- * |. o.| || All Rights Reserved *
- * | . | || Written by John Toebes and Doug Walker *
- * | o | || The Software Distillery *
- * | . |// 235 Trillingham Lane *
- * ====== Cary, NC 27513 *
- * BBS:(919)-471-6436 *
- \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- This material is Copyright (C) 1988 and 1989 The Software Distillery.
- It may be distributed freely as long as the following restrictions are met:
-
- 1. All files present in the distribution package must be redistributed
- with the package, including this documentation file. If you
- distribute on diskette, all files must be on a single diskette.
-
- 2. The distributor may charge a fee to recover distribution costs.
- The fee for diskette distribution should not be more than the cost
- to obtain the same diskette from Fred Fish or The Software Distillery,
- whichever is greater. Current charge from The Software Distillery
- is $6 per disk, including all postage and handling charges.
-
- 3. The distributor agrees to cease distributing the programs and data
- involved if requested to do so by authors or any member of The
- Software Distillery.
-
- ------------------------------DISCLAIMER
-
- Neither The Software Distillery nor any of its members will be liable for
- any damage arising from the failure of this program to perform as described,
- or any destruction of other programs or data residing on a system
- attempting to run the program. While we know of no damaging errors, the
- user of this program uses it at his or her own risk.
-
- ============================================================================
-
- Welcome to the MemWatch Library! You may be familiar with MemWatch I
- and II. The MemWatch library adds lots of memory debugging features
- that you link into your program. MemWatch III, under development now,
- will communicate with these routines to provide asynchronous memory
- checking - that is, the external MemWatch III process will tell you if
- your program abuses its own memory.
-
- The MemWatch library compiles under Lattice C 5.02 and may work under
- previous versions. Lattice users can link with the provided library;
- if the memory features are turned off, no additional code will be linked
- in. Manx users may link the routines in with their code by linking in
- the .o files 'mwcontrol.o', 'mwalcfre.o' and 'mwreport.o', but they will
- have to remove these .o files if they remove the memory debugging
- features. I have not tried to compile this code with Manx, but I know of
- no reason why it wouldn't work.
-
- The program-level memory debug routines are controlled by a
- preprocessor symbol, MWDEBUG, and are #defined to nothing if the
- symbol is not defined. To link the program-level routines into
- your code, do the following:
-
- 1. Include the file "memwatch.h" into each file that will be
- allocating or freeing memory. (Don't include "mempriv.h" - it is
- for the internal use of the memwatch.lib routines only).
-
- 2. #define the symbol MWDEBUG at some point before memwatch.h is
- included. This could be in another include file, or in the
- program file. If the symbol MWDEBUG is not defined, all the
- MemWatch routines disappear, thus adding nothing to your code
- size.
-
- 3. Insert a call to the function MWInit in your main() program
- before any memory calls.
-
- 4. Insert a call to MWTerm in your main() program just before
- it exits. If you use exit() to exit from multiple places,
- try
-
- #define EXIT(rc) {MWTerm(); exit(rc);}
-
- and replace all occurrences of exit with EXIT.
-
- The program-level MemWatch interface is described below.
-
- ---------------------------------------------------------------------
-
- void MWInit(FILE *debugfile, LONG flags);
-
- Call this routine exactly once, before any other memory allocation
- calls.
-
- The debugfile is a file opened with the fopen() function to be
- used for all debugging messages. If debugfile is NULL, stdout
- will be used. If the MWF_NOLOG flag is on (see below), no
- debugging file will be used.
-
- The flags can be one or more of the following, ORed together if
- necessary:
-
- MWF_EXT: If set, attempt to communicate with the external MemWatch
- process. The external process under development, so don't
- set this flag until it is available or you will get
- warning messages.
-
- MWF_NOLOG: If set, do not print error or warning messages.
-
- MWF_NOCHECK: If set, do not check all allocated memory each time
- a memory routine is called. If not set, every
- AllocMem, FreeMem, malloc or free call will cause all
- allocated memory to be examined. This can be slow, but
- it's safe.
-
- MWF_NOFREE: If set, do not free memory left allocated when the
- program exits. If not set, any memory you allocated
- and did not free will be freed on your behalf.
-
- MWF_NOFTRASH: If set, freed memory will not be trashed. This does
- save some time, but it is valuable to trash freed memory
- to verify you aren't still using it.
-
- MWF_NOFKEEP: If set, free memory immediately when FreeMem or free is
- called. If not set, 'freed' memory will actually be kept
- on a chain and checked periodically for a change in its
- value. If the value changes, you have written to freed
- memory. MWF_NOFTRASH implies MWF_NOKEEP, since there is
- no point in keeping memory that you don't know the value
- of. If this flag is NOT set, kept memory will be freed
- if the machine actually runs out of memory.
-
- MWF_NOATRASH: If set, memory will not be trashed upon allocation. This
- also saves some time, but it is extremely valuable to trash
- allocated memory to be sure you aren't relying on side
- effects for your program to run correctly.
-
-
- ---------------------------------------------------------------------
-
- void MWTerm(void);
-
- Call this routine exactly once, after all memory functions have
- been completed. It will always generate a check, even if MWF_NOCHECK
- has been set.
-
- ---------------------------------------------------------------------
-
- char *MWAllocMem(LONG size, LONG flags, char *file, int line);
- void *MWmalloc(unsigned n, char *file, int line);
-
- You should not call these routine directly, but your AllocMem
- and malloc calls will be defined to call them if the symbol MWDEBUG
- is defined.
-
- !!!NOTE: MWmalloc is not a complete substitute for the malloc()
- function!!!! In particular, malloc allows you to access the last
- piece of malloc'ed memory freed; MWmalloc does NOT allow this!!
- I stuck this in 'cause it was easy; if it breaks your program, either
- remove the #define, implement MWmalloc correctly, or complain to me.
- realloc() is NOT SUPPORTED.
-
- ---------------------------------------------------------------------
-
- void MWFreeMem(char *ptr, LONG size);
- int MWfree(void *b);
-
- You should not call these routine directly, but your FreeMem
- calls will be defined to call them if the symbol MWDEBUG is defined.
-
- ---------------------------------------------------------------------
-
- void MWReport(FILE *reportfile, char *title, int level);
-
- Call this routine any time you want a report on how much memory
- you are using. The 'reportfile' is a file to send the report
- to. If reportfile is NULL, the debug log file will be used.
-
- 'title' is any character string you want. It will be used to
- label the dumped output. Use NULL for no title.
-
- 'level' tells how much detail you want in the report. It is one
- of the following values:
-
- MWR_NONE - Don't print anything.
- MWR_SUM - Print current and total memory usage
- MWR_FULL - Print a short description of each outstanding allocation
-
- ---------------------------------------------------------------------
-
- void MWCheck(void);
-
- Call this routine when you want to verify all your allocations are
- clean. If you haven't set the MWF_NOCHECK flag, all allocations
- are checked every time you do an Alloc or Free operation anyway,
- but you might want to use this directly if you set the flag or if
- you go long periods of time without allocating memory.
-
- ---------------------------------------------------------------------
-
- void MWLimit(LONG chip, LONG fast);
-
- Call this routine if you want to set an artificial 'cap' on the
- amount of memory available. Any allocations that ask for memory
- that would push your total allocation above the specified limits
- will fail, even if memory is available to fill them. Keep in mind
- that this doesn't take fragmentation into account, so it doesn't
- guarantee your program will work on a smaller memory machine!
- You can simulate out-of-memory conditions by calling MWLimit
- with (0,0) - no allocations will ever succeed until the limit
- is raised above the current usage level.
-
- The 'chip' parameter sets a limit on chip memory; the 'fast'
- parameter sets a limit on fast memory. If the specified limit for
- a category is -1, the limit will be set at the current usage amount.
- Thus, any frees you do will improve your situation.
-
- If you want to remove a limit, set it to some extremely large value,
- like 0x7fffffff.
-
-
- ---------------------------------------------------------------------
-
-
- The enclosed program 'test' will test the memlib functions for you.
- Invoke it by typing 'test' from CLI. You will get a prompt like
-
- Enter command (h for help):
-
- If you type 'h', it will say
-
- Commands are:\n");
- A <n> --> Allocate 'n' bytes, replace current allocation
- W <n> --> Write 'n' bytes to most recent allocation
- F <n> --> Free 'n' bytes starting at most recent allocation
- R <lvl> --> Report on usage; <lvl> is 1 for less, 2 for more detail
- C --> Check all allocations, report errors
- Q --> Quit program
-
- Basically, the 'A' command calls AllocMem; the 'F' command calls FreeMem;
- the 'W' command writes zeroes to the last memory allocated with 'A', even
- if it has been freed in the meantime; the 'R' command calls MWReport; and
- the 'C' command calls MWCheck.
-
-
- Here are some examples of running test:
- >
- > Enter command (h for help): a 10
- > 10 bytes allocated, value 0x00221254
- >
- > Enter command (h for help): w 11 <-- Wrote over the end!
- > 11 bytes cleared
- >
- > Enter command (h for help): c
- > MemWatch ERROR: Trailer trashed
- > 0x00221254 length 10 allocated line 36 file test.c
- > Check complete
- >
- >
- >
- > Enter command (h for help): q
- > MemWatch ERROR: The following allocations were not freed:
- > 0x00221254 length 10 allocated line 36 file test.c
-
- -------------------------------------------------------------------------
- >
- > Enter command (h for help): a 100
- > 100 bytes allocated, value 0x002232cc
- >
- > Enter command (h for help): f 100
- > 100 bytes freed
- >
- > Enter command (h for help): w 10 <-- Wrote to mem after free!
- > 10 bytes cleared
- >
- > Enter command (h for help): c
- > MemWatch ERROR: Freed memory modified
- > 0x002232CC length 100 allocated line 36 file test.c
- > Check complete
- >
- >
- >
- > Enter command (h for help): q
-
- -------------------------------------------------------------------------
-
- > Enter command (h for help): a 1000
- > 1000 bytes allocated, value 0x002b073c
- >
- > Enter command (h for help): f 1000
- > 1000 bytes freed
- >
- > Enter command (h for help): f 1000 <-- Freed memory twice!
- > Invalid FreeMem call, addr 0x002B073C length 1000
- > 1000 bytes freed
- >
- > Enter command (h for help): a 10
- > 10 bytes allocated, value 0x00229ee4
- >
- > Enter command (h for help): f 5 <-- Freed too few bytes!
- > FreeMem called with length 5 on the following allocation:
- > 0x00229EE4 length 10 allocated line 36 file test.c
- > 5 bytes freed
- >
- > Enter command (h for help): q
- > MemWatch ERROR: The following allocations were not freed:
- > 0x00229EE4 length 10 allocated line 36 file test.c
-