          MSS - Memory Supervision System Version 1.2 Documentation

        +-----------------------------------------------------------+
        | MSS - Memory Supervision System Version 1.2 Documentation |
        +-----------------------------------------------------------+
        | Written by                                                |
        | Juan Jesus Alcolea Picazo, a920101@zipi.fi.upm.es         |
        | and Peter Palotas, blizzar@hem1.passagen.se               |
        +-----------------------------------------------------------+
        | Version 1.2, Last updated 1998-11-12                      |
        +-----------------------------------------------------------+
----------------------------------------------------------------------------
This is the complete documentation for MSS, the Memory Supervision System
version 1.2, written by Juan Jesus Alcolea Picazo and Peter Palotas.
----------------------------------------------------------------------------

                                +----------+
                                | Contents |
                                +----------+
1. Introduction
2. Compiling and installing MSS
3. Using MSS
4. Configuring MSS
5. Function Reference
6. History
7. Contacting the authors
8. Copyright

----------------------------------------------------------------------------
                            +-----------------+
                            | 1. Introduction |
                            +-----------------+
1.1 What is MSS?
1.2 But what does it really do?
1.3 Does it work with my compiler
1.4 Do I have to pay for MSS?
1.5 Where can I get the latest version of MSS?

                            +------------------+
                            | 1.1 What is MSS? |
                            +------------------+
During the development of C/C++ programs dynamic memory is often allocated
using either the standard C malloc family of functions or the C++ operators
new and delete. When allocating and using dynamical memory, the programmer
often make mistakes which might lead to errors during program execution, so
called bugs. This could be that the program "forgets" to delete/free some
memory (so called memory leaks), tries to access more memory than it
allocated and a lot more. Discovering and tracking these errors is a very
difficult task, and often the errors go by without the programmer noticing
them because the program may appear to work correctly anyway. Therefore MSS
was developed, to assist programmers in detecting such bugs and producing
better programs.

MSS is a free (GPL) C/C++ library that helps you in the infamious task of
finding bugs related to dynamical memory during the development of your
programs. With MSS you will easily be able to detect the following bugs in
your programs:

  * Memory leaks
  * Use of uninitialized memory
  * Zero-length allocations
  * Out of range block accesses
  * Bogus or repeated deallocations
  * Unsuccessful allocations
  * "Wild" or corrupted pointers
  * And more...

MSS can also give you a lot of information about the state of the dynamical
memory allocated by your program at any point during the execution, for
example:

  * Total allocated memory
  * Maximum allocated memory since program start
  * Number of specific allocation/deallocation functions successfully
    called
  * Number of blocks allocated
  * List of blocks allocated, including the module, function and line
    number where the allocation took place.

MSS is also very easy to use. Your current sources will only require minor
changes, to enable the usage of MSS.

                    +---------------------------------+
                    | 1.2 But what does it really do? |
                    +---------------------------------+
MSS filters all your calls to the C functions malloc(), calloc(),
realloc(), xmalloc(), xrealloc(), xfree(), cfree(), free() and strdup() and
if you have a C++ compiler, also the C++ operators 'new' and 'delete'. It
keeps an internal list of all the allocated blocks, together with
information about where the memory was allocated, how it was allocated and
some other information.

All interesting events, such as memory allocations/deallocations, detected
bugs and so on are written to a log file (which also may be one of the
standard streams stdout or stderr) which reflects all the dynamic memory
related activities of your program.

You are also provided with a set of functions to control various features
of MSS, and to get some interesting info in run-time, such as maximum used
dynamic memory since program start and a lot of others.

You can also check that allocated memory blocks are still valid (constant
blocks), that no out of range writings has occured. You can check if a
certain pointer points to a valid block of memory, and a lot of other
things.

When you are ready to release your project you do not have to remove all
calls to the MSS function calls, because they will all compile away to
nothing if you have not defined the symbol "MSS" to the preproccessor.

                   +------------------------------------+
                   | 1.3 Does it work with my compiler? |
                   +------------------------------------+
MSS was written with the intention of being fully portable to any
compiler/platform that supports the ANSI C/C++ standard. Since the C++ ANSI
standard was just recently finished however, there are a lot of diffrent
C++ dialects out there, and some may not be fully compatible with the C++
section of MSS. Some configuring options were therefore added to make MSS
support as many compilers as possible. The C section of MSS however, should
be fully ANSI compliant and therefore work with all ANSI compatible C
compilers, with only minor configuration.

MSS was written using GCC 2.7.2.1, and has also been tested using GCC
2.8.0, GCC 2.8.1 and EGCS-1.1 and it compiles without any problems on these
compilers. This also goes for the excellent DJGPP, the DOS port of GCC
(with which MSS actually was developed). If your compiler is a 32-bit
compiler for the i386 family of processors, building MSS should be no
problems, other platforms are untested, but any reports of successful (or
unsuccessful) usage of MSS are very welcome.

Currently there are two "makefiles" supplied with this package. One
makefile was written for usage with the GNU C/C++ compiler (GCC) and GNU
Make. (It will also require the GNU Fileutils for some operations), this is
called "Makefile". The other one is a project-file for Borland C++ 5.02,
composed by Rolf F. Katzenberger, this one is called "borland.ide". However
we really would like to include more makefiles with MSS, so if you have
another compiler, and are able to write a makefile for it, please do so and
send it to us. We will be glad to include it in our next release.

If you use another compiler, and can't seem to get MSS to work with it,
don't hesitate to contact us. We will do everything we can to help you.

                      +-------------------------------+
                      | 1.4 Do I have to pay for MSS? |
                      +-------------------------------+
No, you will never have to pay anything for using MSS. MSS is free
software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

             +------------------------------------------------+
             | 1.5 Where can I get the latest version of MSS? |
             +------------------------------------------------+
The latest version of MSS can always be found at
http://hem1.passagen.se/blizzar/mss/index.html.

MSS is also available from various FTP-sites. Among others it should be
available from ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/mss12.zip
and ofcourse from any other simtelnet mirror. Note that it is not a DJGPP
specific version, but it will (should) work with any ANSI C compliable
compiler.

----------------------------------------------------------------------------
                    +---------------------------------+
                    | 2. Compiling and Installing MSS |
                    +---------------------------------+
2.1 Unpacking the archive
2.2 Configuring MSS for your compiler
2.3 Compiling and installing MSS using GCC
2.4 Compiling and installing MSS using Borland C++ 5.02
2.5 Compiling and installing MSS using another compiler.

                        +---------------------------+
                        | 2.1 Unpacking the archive |
                        +---------------------------+
You have to unpack the archive preserving the directory structure.
Depending on your platform there are diffrent was to do this, but under
linux the 'unzip' program automagically preserves the directory structure,
and in DOS you should specify the '-d' switch to 'pkunzip'.

Start by unpacking the archive in a proper directory, under DJGPP we
recommend "%DJDIR%/contrib/", i.e. the contrib directory in the directory
where you installed DJGPP, usually 'C:\DJGPP\CONTRIB\' or something like
that.

pkunzip -d mss12.zip
or
unzip mss12.zip
MSS will unzip itself into its own directory, './mss12/' (under DJGPP this
will be %DJDIR%/contrib/mss12 if you followed the above recommendation), so
there is no need to create a separate directory for MSS before unzipping
the archive.

If you are using GCC, either under DOS or Linux this is a pretty easy task.

                  +---------------------------------------+
                  | 2.2 Configuring MSS for your compiler |
                  +---------------------------------------+
There are some configuring options available to make MSS more portable to
diffrent compilers. These options can be found in the file `mss.h', and
consist of preprocessor directives (#define statements) in the beginning of
the file (all marked clearly with comments). Some options may need to be
defined to a specific value, and others control the behaviour of MSS by
being enabled/disabled which is achieved by commenting out a #define
statement, or leaving it uncommented.

The following options may be configured in `mss.h':

+-----------------------------+--------------------------------------------+
| MSS_PTR_SIZE_T              | This option must be defined. It should be  |
|                             | defined to an integer type that is large   |
|                             | enough to hold the value of a pointer.     |
|                             | Default value for this is size_t.          |
+-----------------------------+--------------------------------------------+
| MSS_PRINTF_SIZE_T           | This option must be defined. It should be  |
|                             | defined to a type specifyer string         |
|                             | constant that will make printf()           |
|                             | correctly print an argument of type        |
|                             | MSS_PTR_SIZE_T. (Ex. if MSS_PTR_SIZE_T is  |
|                             | defined to unsigned long this option       |
|                             | should be defined to "%lu"                 |
+-----------------------------+--------------------------------------------+
| MSS_FUNCTION_MACRO          | This option must be defined. It should be  |
|                             | defined to a predefined macro, or a        |
|                             | string variable provided by your compiler  |
|                             | that represents the name of the function   |
|                             | in which it was found. (Set it to a        |
|                             | string constant in case your compiler      |
|                             | doesn't provide such a macro, ex.          |
|                             | "unknown"). (GNU C Uses                    |
|                             | __PRETTY_FUNCTION__ or __FUNCTION__), and  |
|                             | by default it is defined to                |
|                             | __PRETTY_FUNCTION__. Borland users need    |
|                             | to change this to "(unknown function)" or  |
|                             | "?" or something, since Borland does not   |
|                             | supply such a function macro.              |
+-----------------------------+--------------------------------------------+
| MSS_DEFINE_NEW_DELETE_ARRAY | Some compiler needs a redefinition of      |
|                             | new[] and delete[], some don't (these      |
|                             | should be rare nowadays). If your          |
|                             | compiler does, define this, otherwise      |
|                             | don't (comment it out). GCC wants this     |
|                             | defined, whereas Microsoft Visual C++ 1.5  |
|                             | does not.                                  |
|                             | If you do not know wether or not your      |
|                             | compiler wants this defined, try           |
|                             | compiling with this option enabled first,  |
|                             | and disable it only if it doesn't work.    |
+-----------------------------+--------------------------------------------+
| MSS_USE_EXCEPTIONS          | This should be defined if your compiler    |
|                             | supports exceptions. If you get a          |
|                             | warning/error about operator delete        |
|                             | throwing diffrent exceptions (or           |
|                             | something like that) try toggeling this,   |
|                             | that should help. (GCC 2.8.0 supports      |
|                             | exceptions and wants this enabled,         |
|                             | earlier versions does not. (With           |
|                             | PGCC-2.90.23 based on EGCS 1.0.1 this      |
|                             | should be defined). Anyway, if you get     |
|                             | the errors above, try undefining this if   |
|                             | defined, and defining it if undefined.     |
|                             | (If you're not compiling with C++          |
|                             | support, you don't need to worry about     |
|                             | this).                                     |
+-----------------------------+--------------------------------------------+
| MSS_DTOR_AFTER_ATEXIT       | This option should be defined in case      |
|                             | your compiler will run the destructors of  |
|                             | global objects after any functions         |
|                             | registered with the atexit() function. It  |
|                             | is not essential that this setting is      |
|                             | correct for MSS to work, but it will make  |
|                             | the logfile look nicer. If your compiler   |
|                             | is advanced enough to follow the C++       |
|                             | standard that says that any "exit          |
|                             | functions", including both destructors of  |
|                             | global objects and functions registered    |
|                             | with atexit should be called in the        |
|                             | reverse order that they were registered,   |
|                             | i.e. they will be mixed. In that case you  |
|                             | will just have to test by toggling this    |
|                             | option and see what gives the nicest       |
|                             | looking result. Remember, whatever         |
|                             | setting you choose for this option, it     |
|                             | will never lead to a sever error or crash. |
+-----------------------------+--------------------------------------------+
| MSS_DISABLE_THREADING_FUNC  | These options must be defined. They are    |
| MSS_ENABLE_THREADING_FUNC   | useful in multithreading environments.     |
|                             | They should point to a function disabling  |
|                             | respectively enabling threading. This is   |
|                             | not a very good solution, and it is        |
|                             | likely to change in the future, but at     |
|                             | present it's all there is to make the      |
|                             | program threading safe. These are defined  |
|                             | to nothing by default.                     |
+-----------------------------+--------------------------------------------+
               +--------------------------------------------+
               | 2.3 Compiling and installing MSS using GCC |
               +--------------------------------------------+
Since MSS was developed using GCC, and comes with a makefile for GCC, this
should not be any problems, unless you use a really old version of GCC. You
might however need to configure MSS before compiling, changing one of the
compiler-specific options.

NOTE! If you have GCC but not G++, the GNU C++ compiler, you will want to
uncomment the 'NOCPP=.' line in the makefile (Remove the '#' sign in front
of that line). If you have C++ support however, do not uncomment that line,
even if you are only going to use the library in plain C projects.

Enter the MSS directory, and enter 'make all'. This should compile
everything, making the library and test programs.

If you want to install the package to its default locations which are:
  * DJGPP: Headerfiles go into %DJDIR%/include, the library goes into
    %DJDIR%/lib.
  * LINUX: Headerfiles go into /usr/local/include, the library goes into
    /usr/local/lib

just enter 'make install'. If you want to install MSS to another location,
edit the makefile and change the LIBDEST and INCLUDEDIR parameters under
the correct section.

There are a few more rules in this makefile, of which all are listed here.

  * make all
    This will compile everything both the library and the sample programs.
    The library will be placed in lib/[linux|djgpp]/libmss.a, and the
    sample-programs are located in the samples directory.

  * make lib
    This will compile the library only.

  * make test
    This will compile the test programs, and the library if it is not
    present. (Same as make all)

  * make install
    This will install the library to /usr/local/lib/libmss.a under linux,
    or %DJDIR%/lib/libmss.a under DJGPP, and the headerfile (`mss.h') will
    go in /usr/local/include under linux, and %DJDIR%/include under DJGPP.
    You can change LIBDEST and INCLUDEDIR in the makefile (under either the
    DJGPP or linux section) if you want these files installed to another
    place, or copy them manually.

  * make clean
    This will remove all objectfiles for the specific environment, i.e. if
    `make clean' is run under Linux it won't remove the DJGPP object files,
    and vice versa.

  * make cleanall
    This will remove all rebuildable files, excluding any installed ones.

  * make uninstall
    This will uninstall any installed files, i.e. remove them.

  * make fixlibc
    This is useful under DJGPP only. If you are using version 2.01 of DJGPP
    (Or possibly also version 2.00) there is a bug in libc, which will make
    it impossible to write stuff to files from destructors, since all files
    will be closed before the destructors are called. This package includes
    the file `exit.c' from an alpha version of DJGPP, version 2.02, where
    this bug was fixed. `make fixlibc' will compile this file and patch
    your libc, which it assumes to find under %DJDIR%/lib/libc.a Do make a
    backup of your libc before installing this patch just to be sure,
    especially if you are using a version other than 2.01 of DJGPP.

MSS comes with a few documented sample programs that will show you some of
MSS's capabilities and how you might use MSS to locate bugs. These files
are located in the samples directory. See the file README in that directory
for more information.

        +---------------------------------------------------------+
        | 2.4 Compiling and installing MSS using Borland C++ 5.02 |
        +---------------------------------------------------------+
The directory MSS was installed to is further called the MSS root
directory. Locate mss.h in the MSS root directory and open it. Comment out
the definition of MSS_FUNCTION_MACRO and replace it by #define
MSS_FUNCTION_MACRO "(unknown function)".

Targets in the project file

Now open borland.ide in your IDE. You will notice eight target nodes plus
one source pool node:

  +------------------+--------------------------------------------------+
  | mss32.lib        | MSS library, no debugging code                   |
  +------------------+--------------------------------------------------+
  | mss32MT.lib      | MSS library, no debugging code, multithreaded*   |
  +------------------+--------------------------------------------------+
  | mss32debug.lib   | MSS library, with debugging code                 |
  +------------------+--------------------------------------------------+
  | mss32MTdebug.lib | MSS library, with debugging code, multithreaded* |
  +------------------+--------------------------------------------------+
      +-------------+------------------------------------------------+
      | test1_1.exe | MSS test program as included in the MSS relase |
      +-------------+------------------------------------------------+
      | test1_2.exe | MSS test program as included in the MSS relase |
      +-------------+------------------------------------------------+
      | test1_3.exe | MSS test program as included in the MSS relase |
      +-------------+------------------------------------------------+
      | test2_1.exe | MSS test program as included in the MSS relase |
      +-------------+------------------------------------------------+
         +------------+-------------------------------------------+
         | MSSSources | source pool referenced by all lib targets |
         +------------+-------------------------------------------+
All test programs get linked with mss32.lib. I have tested mss32debug.lib,
too, but none of the multithreaded libs. Also, I haven't tried to build
16-Bit libs, just in case you might wonder.

* Please note that you have to modify mss.h to deal with multithreading.
See the details on MSS_DISABLE_THREADING_FUNC and
MSS_ENABLE_THREADING_FUNC. Without that modification, the multithreaded
libraries might not work.

Configuring the project file

Under "Options | Project | Directories" adjust the "Include" and "Library"
directories so that they match your environment. If you have set an
environment variable BCROOT to contain the root directory of your
environment, then you don't need to make any modifications. Otherwise you
have to replace each occurence of $env(bcroot) by that root directory, e.g.
c:\bc5.

Compiling

In the MSS root directory, you will have found two subdirectories "lib" and
"objs". Each of these directories contain a directory named "borland".
These subdirectories will contain the *.obj and *.lib files. (Should you
ever want to change these locations, be sure to adjust the "Intermediate"
and "Final" directories under Options | Project | Directories accordingly).

Now run "Project | Build all" to compile all libraries and test programs.
Please note that all object files are written into the same directory, so
just running "Project | Make all" would produce corrupt libraries.

After that, all *.lib files can be found in the "lib\borland" subdirectory.
All test executables can be found in the "samples" subdirectory.

If you have trouble compiling MSS under Borland C++ v5.02, please feel free
to mail me under rfkat@ibm.net. However, please direct questions directly
pertaining to MSS to Peter Palotas at blizzar@hem1.passagen.se.

        +---------------------------------------------------------+
        | 2.5 Compiling and installing MSS using another compiler |
        +---------------------------------------------------------+
If you are using another compiler, you will have to write your own makefile
or compile the library manually. The library should consist of the
following files:

  * alloc.c
  * check.c
  * cppspec.cc (only if your compiler supports C++)
  * list.c
  * inifile.c
  * config.c
  * init.c
  * internal.c
  * log.c
  * inifile.c
  * user.c

You might have to rename the .cc files to .cpp for some compilers.
(Probably for most DOS based ones).

After compiling these files and generating the library, the library and the
include file `mss.h' has to be copied to somewhere where your compiler will
find them. Read the manual for your specific compiler.

MSS comes with a few documented sample programs that will show you some of
MSS's capabilities and how you might use MSS to locate bugs. These files
are located in the samples directory. See the file README in that directory
for more information.

----------------------------------------------------------------------------
                              +--------------+
                              | 3. Using MSS |
                              +--------------+
3.1 How to make your program use MSS
3.2 Functions provided by MSS
3.3 What do these warnings in the logfile mean?
3.4 Hints & Tips
3.5 Known Problems With MSS

                  +--------------------------------------+
                  | 3.1 How to make your program use MSS |
                  +--------------------------------------+
Making your program use MSS is as we have mentioned earlier really simple.
All you have to do is to add `#include <mss.h>' at the very top of every
C/C++ source file in your project. Note that you have to add this line to
all files in your project, or MSS will not work correctly. To actually
enable MSS you will also have to define the symbol MSS, and link your
program with the MSS library.

If you are using GCC, you can simply define the MSS symbol by specifying
-DMSS on the commandline to gcc, and specify -lmss to link with the MSS
library. To achieve best performance, you should specify the MSS library as
the very last library on the commandline. This is because MSS wants to know
when your program exits, and if you don't specify MSS as the last library,
it might think your program exits before it really does, due to the way
destructors are called. (This does not affect C projects though, nor will
it cause any errors or anything, it will just print that the program exits
before it really does to the log file, hence making it look like some
allocations/deallocations occured after the program exit. This is extremely
rare though, and you normally don't have to worry about this).

Every call to 'new', 'delete', 'malloc', 'calloc', 'realloc', 'xmalloc',
'xrealloc', 'cfree', 'xfree', 'free' and 'strdup' will be filtered and
processed by MSS, and a logfile will be created. (Or logging will be
written to stdout/stderr, depending on your configuration). You might
notice a minor(?) speed degradation when running your program using MSS
(sometimes, depending on how MSS is configured, the speed degradation can
be very big, which might make you think the program has crashed), otherwise
you shouldn't notice anything diffrent about your program. (Other than the
fact that you probably will get fewer crashes). The logfile created will
contain information about all allocated memory, when the
allocations/deallocatios occured, if any errors has been detected and so
on. Depending on the configuration options to MSS the logfile can sometimes
become very large, so be aware of this so that you have enough free
diskspace.

                      +-------------------------------+
                      | 3.2 Functions provided by MSS |
                      +-------------------------------+
MSS provides a lot of functions that your program might call to get
information about the current memory situation, or affect the logging in
some way which is what most of the functions do. All functions are called
through macros, which all compiles away to nothing in case the preprocessor
symbol 'MSS' was not defined. This feature makes it easy to switch between
"debug" and "release" mode, in case you want to for an example test the
real speed with which your program will run this comes quite in handy.

For a complete reference of all the functions, see the Function Reference.

         +--------------------------------------------------------+
         | 3.3 What do those warnings in the logfile really mean? |
         +--------------------------------------------------------+
The MSS logfile sometimes produces warnings which may seem strange at
first, therefore we have decided to explain the meaning of some terms here.

+------------------------------------+-------------------------------------+
| Prefix Corrupted                   | You have written some data out of   |
|                                    | the limits of the described block.  |
|                                    | Specifically, you've done it        |
|                                    | before the start of the block.      |
|                                    | This is mainly caused by using      |
|                                    | 'signed' numbers as array indexes   |
|                                    | or pointer displacements on some    |
|                                    | pointer arithmetic, so you end up   |
|                                    | using negative indexes or           |
|                                    | displacements.                      |
+------------------------------------+-------------------------------------+
| Suffix Corrupted                   | You have written some data out of   |
|                                    | the limits of the described block.  |
|                                    | Specifically, you've done it after  |
|                                    | the end of the block. This is       |
|                                    | typically caused by array           |
|                                    | operations contained in loops that  |
|                                    | go 'too far'. Can also be caused    |
|                                    | by using a too small buffer to      |
|                                    | hold some data.                     |
+------------------------------------+-------------------------------------+
| Trying to delete a non-allocated   | There is no block allocated at the  |
| block                              | address that pointer points to.     |
|                                    | The main reasons for this are:      |
|                                    |                                     |
|                                    | ----------------------------------- |
|                                    | * You have really not allocated     |
|                                    | any block for that pointer.         |
|                                    | ----------------------------------- |
|                                    | * You did, but somehow the pointer  |
|                                    | has been altered and it's original  |
|                                    | value lost (maybe you where using   |
|                                    | it as an index?).                   |
|                                    | ----------------------------------- |
|                                    | * The pointer was correctly         |
|                                    | pointing to a block of allocated    |
|                                    | memory, but you have deallocated    |
|                                    | it before; that is, you are         |
|                                    | deallocating it twice or more! To   |
|                                    | see if this is what happened, look  |
|                                    | for the same pointer value in the   |
|                                    | log file and see what you did to    |
|                                    | it.                                 |
+------------------------------------+-------------------------------------+
| There is no block starting at      | Same as above. This is issued when  |
| 'address'                          | you request some info about a non   |
|                                    | existent block.                     |
+------------------------------------+-------------------------------------+
| Zero length allocation             | You are requesting an allocation    |
|                                    | for a zero length block. Maybe      |
|                                    | some uninitialized variable or a    |
|                                    | logic or flow bug is causing this   |
|                                    | problem!?                           |
+------------------------------------+-------------------------------------+
| NULL pointer deallocation          | You are deleting a pointer to       |
|                                    | NULL. This will probably result in  |
|                                    | a GP Fault, however it is actually  |
|                                    | legal in C++ (using delete) a       |
|                                    | warning will still be printed,      |
|                                    | since you shouldn't do this. Some   |
|                                    | compilers may not like it! (This    |
|                                    | warning can be disabled for C++     |
|                                    | though, but is normally enabled).   |
+------------------------------------+-------------------------------------+
| Pointer 'p' does not point to any  | You are dealing with a pointer      |
| valid memory                       | that does not point to any legal    |
|                                    | allocated memory. MSS should tell   |
|                                    | you also what are the nearest       |
|                                    | legal blocks. You've probably       |
|                                    | stepped out from any of them. You   |
|                                    | may also be using an uninitialized  |
|                                    | pointer.                            |
+------------------------------------+-------------------------------------+
                            +------------------+
                            | 3.4 Hints & Tips |
                            +------------------+
Here are some notes that you may find useful:
  * First time users of MSS, please study the sample programs in the
    samples directory and their documentations. This is really useful for
    learning some of MSS's capabilities and how you might use it to debug
    your programs. See the file 'README' in the samples directory for more
    information.

  * Keep in mind that all the values that MSS gives you (total memory used,
    blocks, etc...) ignore MSS own use of memory. That is, MSS is
    completely transparent to itself, so you can rely on this values being
    accurate. But notice that the real use of memory when using MSS is
    always higher due to it's own memory needs. They are not much, anyway;
    about 20-30 bytes by memory allocation proccessed. This is increased in
    WatchSize * 2 if WatchLimits is enabled.

  * Be careful about disk space and logging options. An MSS log file with
    all options enabled can be really *big*, specially on big & memory
    intensive programs. In a game I am writing (about 4000+ lines of code),
    I get a 900kb log file! Use MSS even if your program runs without
    problems and you think it has no bugs. It is *incredible* the amount of
    memory related bugs that can be hidind behind an apparent correct
    program. I did this with my game, which was giving no problems, and
    found *TONS* of bugs, some little, some really nasty. I also found a
    BIG memory leak... (in fact, I was frightened after reading the log
    file!).

  * Always remember what options where enabled when reading a log file.
    They are listed at the beginning of it. You may think you have no 'out
    of range write' bugs, while the reality is that MSS was not checking
    them! Note that 'out of range' write check is only done if you
    specifically invoke it at run time (with MSS_CHECK_ALL_BLOCKS or
    MSS_CHECK_BLOCK_AT()) or if CheckOnDealloc or CheckAllOnAlloc is
    enabled at compile time.

  * If you only want to discover hidden bugs, put MSS_DISABLE_LOG_OUTPUT at
    the beginning of your program. This will make MSS log only the
    warnings, and not every legal memory operation. Anyway, it is a good
    practice to inspect at least once the 'memory allocation trace'
    generated by MSS by default. If you get a warning about trying to
    delete a non allocated block, enable FillMemOnAlloc and take a look at
    the direction of the offending pointer; if it is equal to
    FillMemOnAllocValue, then you are deleting a dynamically allocated
    uninitialized pointer. 0x98 is the default FillMemOnAllocValue.

  * If your program crashes, look at the MSS logfile to see where the last
    memory operation was executed. This may give you a hint to isolate the
    bug. It is useful to write little testing programs that create one
    object and then destroys it. You can use MSS to check if all memory has
    been deallocated successfully, or if it is still some memory reserved.
    This is specially useful to check the destructors of complex classes
    that do a lot of dynamic allocations/deallocations. An example:

+-------------------------------------------------------------------------+
| * #include "ctree.h"    //For complex tree class                        |
| #include "mss.h" //For MSS :)                                           |
|                                                                         |
| int main(void)                                                          |
| {                                                                       |
| Ctree * my_tree= new Ctree; //I create a complex tree                   |
| <...Do a lot of operations of node insertion...>                        |
| MSS_LOG_INFO;       //To see number of blocks and memory used.          |
| delete my_tree; //Destroy the tree -> call destructor -> release memory |
| MSS_LOG_INFO;       //To see if there is still any allocated memory.    |
| MSS_LOG_BLOCK_LIST; //To get detailed info about it.                    |
| return 0;                                                               |
| }                                                                       |
+-------------------------------------------------------------------------+
  * Remember, you must put the #include <mss.h> in ALL your C files to
    fully use MSS, or if you want to stop using MSS, you can either delete
    all #include <mss.h>, or not define 'MSS'. You also must not link the
    MSS library to your project. (If you are using only plain C, no C++,
    you can still link the library if you want to, making it very easy to
    disable MSS. Simply don't define 'MSS'). If you forget putting #include
    <mss.h>in any of your project's C++ files, MSS will not be able to get
    detailed info about memory allocations or deallocations (I mean line
    number, module name and function name), but it will still handle all
    loggings correctly. This loggings will appear as: "LOG: unknown (line 0
    of unknown) allocated 20 bytes at 51120.".
    The same applies to precompiled modules linked with your application.
    However, this does not apply to C files. If you forget to include
    `mss.h' in your C files MSS will not intercept and detect any
    allocations/deallocations.

  * Please, if you use MSS, mail us and tell us. We'd really like to hear
    from you! Any comments, suggestions, etc... are highly appreciated.
    Thanks :).

                      +-----------------------------+
                      | 3.5 Known problems with MSS |
                      +-----------------------------+
Currently there is only a few serious known problem with MSS. If your
program overloads the operator new your program will not work correctly
with MSS. Also if you make your own #define free <something> or any other
allocation function MSS will not work. Currently we have no good solution
to these problem, but if you come up with anything, please contact us.

----------------------------------------------------------------------------
                           +--------------------+
                           | 4. Configuring MSS |
                           +--------------------+
4.1 General information
4.2 Configuration file syntax
4.3 Specifying where to write logging output
4.4 Options concerning error detection
4.5 Options concerning the layout of the logfile

                        +--------------------------+
                        | 4.1 General information. |
                        +--------------------------+
This chapter discusses the configuration which affects MSS while it is
running, which mostly includes what kind of error checking to perform, and
the layout of the logfile.

All compiler specific configurations should be made either in the makefile
(if you are using GCC) as discussed in Compiling and installing MSS using
GCC, or in `mss.h' which is discussed in Configuring MSS for your compiler.

All run-time specific configurations are either read from special
configuration files at run-time, or the internal hard-coded values are
used. The special configuration files does not need to contain all
available configuration options, only the ones that it should override. The
configuration is made in the following order;

  * Internal hard-coded values are "read".
  * Global configuration file (if present) is read, overriding the
    hard-coded values.
  * Local configuration file (if present) is read, overriding any previous
    read values.

There is no need to have any configuration file present, and in that case
the hard-coded values are used. If you wish to use a global configuration
file, this file will be read by any program that uses MSS, the environment
variable `MSS_CFG' should contain the full path to this file. The option
`LocalCFGFile' in this file specifies the name of the local configuration
file (if this option is not available the hard-coded value `mss.cfg' will
be used. The local configuration file is always expected to be found in the
directory from which the program is run (NOTE that your program must not
change directories before the first call to an MSS function or a memory
allocation function if the local configuration file should be found). If
this files exists, any options available in it will override the options
previously read from any global configuration file or the hard-coded values.

Please note that you do not need to have both configuration files present.
You can choose only to have the local or the global file or none of them.
It is however recommended that you create a global configuration file, so
that you are sure on which options are enabled.

                      +-------------------------------+
                      | 4.2 Configuration file syntax |
                      +-------------------------------+
The syntax of the configuration files is really simple, and is very similar
to for an example the windows ini files except there are no sections. The
purpose of the configuration files are to set various options to diffrent
values. The general syntax is:

<OptionName> = ["]<Value>["]

Where <OptionName> is the name of the option, and <Value> is the value you
wish to set this option to. The value can be quoted if you wish to, but
this is not neccessary unless you want to include whitespaces at the
beginning or the end of the value. There are some values that have a
special meaning if a boolean (true/false) value it expected. You can set a
boolean option to either "True", "1" or "Yes" to specify a true value, or
"False", "0" or "No" to specify a false value. Note that all integer values
can be specified in decimal or hexadecimal form (ex. 0x10). If you want the
option to include a quote ("), a newline or some other special character
you need to escape it. The following escape codes are recognized by MSS:

                   +-----------------+------------------+
                   | Escape Sequence | Meaning          |
                   +-----------------+------------------+
                   | \\              | Single backslash |
                   +-----------------+------------------+
                   | \n              | Newline          |
                   +-----------------+------------------+
                   | \r              | Carriage Return  |
                   +-----------------+------------------+
                   | \"              | Double Quote     |
                   +-----------------+------------------+
                   | \t              | Tab              |
                   +-----------------+------------------+
Comments are also allowed in the config file, on an empty line. They should
be preceeded by a #-sign.

Let's show you an example:

                  +---------------------------------------+
                  | # This is a comment                   |
                  | LogFileName = "mss.cfg"               |
                  |                                       |
                  | # False and No have the same meaning. |
                  | LogToStdout = False                   |
                  | LogToStderr = No                      |
                  |                                       |
                  | NewLineString = "\n"                  |
                  +---------------------------------------+
NOTE! The configuration files are case-insensitive, that is "LogFileName"
is equal to "LOGFILENAME" and "logfilename".

                +------------------------------------------+
                | 4.3 Specifying where to write log output |
                +------------------------------------------+
Logging output can be written either to a file, or any of the standard
output streams (stdout and stderr). This is controlled by the three
configuration options `LogFileName', `LogToStdout' and `LogToStderr'.

+-------------+---------+----------------------------------------+---------+
| Option Name | Type    | Description                            | Default |
+-------------+---------+----------------------------------------+---------+
| LogFileName | String  | The filename to which logging output   | mss.cfg |
|             |         | will be written in case both           |         |
|             |         | `LogToStdout' and `LogToStderr' are    |         |
|             |         | set to false. They are described below |         |
+-------------+---------+----------------------------------------+---------+
| LogToStdout | Boolean | If this is set to true logging output  | False   |
|             |         | will be written to the standard        |         |
|             |         | output (stdout). Note that only one    |         |
|             |         | of `LogToStdout' and `LogToStderr'     |         |
|             |         | may be set to true at the same time,   |         |
|             |         | so always include both of these in     |         |
|             |         | the configuration file.                |         |
+-------------+---------+----------------------------------------+---------+
| LogToStderr | Boolean | If this is set to true logging output  | False   |
|             |         | will be written to the standard error  |         |
|             |         | (stderr). Note that only one of        |         |
|             |         | `LogToStdout' and `LogToStderr' may    |         |
|             |         | be set to true at the same time, so    |         |
|             |         | always include both of these in the    |         |
|             |         | configuration file.                    |         |
+-------------+---------+----------------------------------------+---------+
                 +----------------------------------------+
                 | 4.4 Options concerning error detection |
                 +----------------------------------------+
There are a number of options that lets you specify diffrent methods which
will either make MSS detect errors, or somehow make it easier for the
programmer to detect them. They are listed below:

+------------------------+-----------+---------------------------+---------+
| Option Name            | Type      | Description               | Default |
+------------------------+-----------+---------------------------+---------+
| WatchLimits            | Boolean   | This option               | True    |
|                        |           | enables/disables the      |         |
|                        |           | checking of               |         |
|                        |           | out-of-bounds writes on   |         |
|                        |           | dynamically allocated     |         |
|                        |           | memory blocks. This is    |         |
|                        |           | achieved by allocating    |         |
|                        |           | some extra space on both  |         |
|                        |           | sides of the memory       |         |
|                        |           | block, and filling it     |         |
|                        |           | with a specific value.    |         |
|                        |           | Then upon deallocation    |         |
|                        |           | of the block, or upon     |         |
|                        |           | request from user, this   |         |
|                        |           | extra space is checked.   |         |
|                        |           | If it doesn't all         |         |
|                        |           | contain the same value    |         |
|                        |           | it was filled with then   |         |
|                        |           | an out-of-bound writing   |         |
|                        |           | has occured. It is        |         |
|                        |           | recommended to have this  |         |
|                        |           | option enabled. Although  |         |
|                        |           | it wastes some memory,    |         |
|                        |           | it is one of the most     |         |
|                        |           | powerful features in      |         |
|                        |           | detecting bugs.           |         |
+------------------------+-----------+---------------------------+---------+
| WatchSize              | Integer   | This option specifies     | 32      |
|                        |           | the size of the extra     |         |
|                        |           | space allocated before    |         |
|                        |           | and after any allocated   |         |
|                        |           | blocks, if `WatchLimits'  |         |
|                        |           | was set to true. Bigger   |         |
|                        |           | values give more          |         |
|                        |           | detection power, but      |         |
|                        |           | also more waste of        |         |
|                        |           | memory and the time       |         |
|                        |           | spent checking blocks     |         |
|                        |           | will increase.            |         |
+------------------------+-----------+---------------------------+---------+
| WatchValue             | Integer   | This option specifies     | 0xA8    |
|                        | (0-255)   | the value with which the  |         |
|                        |           | extra space allocated     |         |
|                        |           | before and after any      |         |
|                        |           | allocated blocks if       |         |
|                        |           | `WatchLimits' was set to  |         |
|                        |           | true. Set this to         |         |
|                        |           | anything but zero.        |         |
+------------------------+-----------+---------------------------+---------+
| FillMemOnAlloc         | Boolean   | If this option is set to  | True    |
|                        |           | true, all memory          |         |
|                        |           | allocated will be filled  |         |
|                        |           | with a specific value     |         |
|                        |           | (specified by             |         |
|                        |           | `FillMemOnAllocValue').   |         |
|                        |           | This is useful, since     |         |
|                        |           | programmers often         |         |
|                        |           | accidently rely upon      |         |
|                        |           | uninitialized memory,     |         |
|                        |           | which usually will be     |         |
|                        |           | zero, but with this       |         |
|                        |           | option enabled it will    |         |
|                        |           | all be initialized to     |         |
|                        |           | `FillMemOnAllocValue'     |         |
+------------------------+-----------+---------------------------+---------+
| FillMemOnAllocValue    | Integer   | This option specifies     | 0x98    |
|                        | (0-255)   | the `byte' value with     |         |
|                        |           | which to fill memory      |         |
|                        |           | upon allocation. (see     |         |
|                        |           | `FillMemOnAlloc')         |         |
+------------------------+-----------+---------------------------+---------+
| FillMemOnDealloc       | Boolean   | If this option is         | True    |
|                        |           | enabled all memory will   |         |
|                        |           | be filled with a          |         |
|                        |           | specific value            |         |
|                        |           | (specified by             |         |
|                        |           | `FillMemOnDeallocValue'   |         |
|                        |           | upon deallocation. This   |         |
|                        |           | is useful, since          |         |
|                        |           | programs often use        |         |
|                        |           | memory after it has been  |         |
|                        |           | deallocated (it even      |         |
|                        |           | happened during the       |         |
|                        |           | development of MSS, but   |         |
|                        |           | we had a much harder      |         |
|                        |           | time detecting it than    |         |
|                        |           | you will have with this   |         |
|                        |           | option enabled), and      |         |
|                        |           | with this option enabled  |         |
|                        |           | those bugs will be easy   |         |
|                        |           | to detect.                |         |
+------------------------+-----------+---------------------------+---------+
| FillMemOnDeallocValue  | Integer   | This option specifies     | 0x86    |
|                        | (0-255)   | the value with which to   |         |
|                        |           | fill deallocated memory   |         |
|                        |           | with. (see                |         |
|                        |           | `FillMemOnDealloc').      |         |
+------------------------+-----------+---------------------------+---------+
| CheckOnDealloc         | Boolean   | With this option enabled  | True    |
|                        |           | all blocks will be        |         |
|                        |           | checked for out-of-bound  |         |
|                        |           | writings and constant     |         |
|                        |           | block corruption as they  |         |
|                        |           | are deallocated. It is    |         |
|                        |           | stronglyrecommended that  |         |
|                        |           | you leave this enabled,   |         |
|                        |           | since all blocks really   |         |
|                        |           | should be checked upon    |         |
|                        |           | deletion.                 |         |
+------------------------+-----------+---------------------------+---------+
| CheckAllOnAlloc        | Boolean   | If this option is set to  | False   |
|                        |           | true all blocks will be   |         |
|                        |           | checked for out-of-bound  |         |
|                        |           | writing and constant      |         |
|                        |           | block corruptions every   |         |
|                        |           | time a block is           |         |
|                        |           | allocated/deallocated.    |         |
|                        |           | This can be very          |         |
|                        |           | time-consuming, and is    |         |
|                        |           | usually not neccessary.   |         |
+------------------------+-----------+---------------------------+---------+
| AllocFails             | Integer   | This option should be a   | 0       |
|                        | (0-100)   | number between 0 and      |         |
|                        |           | 100, which indicates how  |         |
|                        |           | many percent of the       |         |
|                        |           | times that malloc are     |         |
|                        |           | called will fail, hence   |         |
|                        |           | returning NULL. This is   |         |
|                        |           | useful for                |         |
|                        |           | stress-testing you        |         |
|                        |           | application, to see if    |         |
|                        |           | it can deal with          |         |
|                        |           | out-of-memory             |         |
|                        |           | situations. If this is    |         |
|                        |           | set to ex. 50,            |         |
|                        |           | malloc/calloc/realloc     |         |
|                        |           | will return NULL about    |         |
|                        |           | every second time it was  |         |
|                        |           | called (average), even    |         |
|                        |           | though they did not       |         |
|                        |           | actually run out of       |         |
|                        |           | memory. Set to zero to    |         |
|                        |           | disable.                  |         |
+------------------------+-----------+---------------------------+---------+
| ExitOnWarning          | Boolean   | If this option is         | False   |
|                        |           | enabled, MSS will exit    |         |
|                        |           | the program as soon as a  |         |
|                        |           | warning is written to     |         |
|                        |           | the logfile. This option  |         |
|                        |           | is disabled by default,   |         |
|                        |           | but if your program       |         |
|                        |           | crashes, and the logfile  |         |
|                        |           | somehow disappears it     |         |
|                        |           | might be useful to        |         |
|                        |           | enable this option.       |         |
+------------------------+-----------+---------------------------+---------+
| WarnOnAllNULLDeallocs  | Boolean   | If this option is set to  | True    |
|                        |           | true, MSS will always     |         |
|                        |           | warn you when trying to   |         |
|                        |           | deallocate a              |         |
|                        |           | NULL-pointer using the    |         |
|                        |           | The reason this warning   |         |
|                        |           | can be disabled, is       |         |
|                        |           | because it is legal to    |         |
|                        |           | deallocate a              |         |
|                        |           | NULL-pointer according    |         |
|                        |           | to the ANSI C/C++         |         |
|                        |           | standard. However, some   |         |
|                        |           | compilers do not like     |         |
|                        |           | this, and crash if you    |         |
|                        |           | try to deallocate a       |         |
|                        |           | NULL-pointer, so it's     |         |
|                        |           | always good practice to   |         |
|                        |           | check for NULL-pointers   |         |
|                        |           | before deallocating       |         |
|                        |           | memory.                   |         |
+------------------------+-----------+---------------------------+---------+
| ZeroLenAllocReturnNULL | Boolean   | If this option is set to  | True    |
|                        |           | true, MSS will always     |         |
|                        |           | return NULL if the user   |         |
|                        |           | program tries to          |         |
|                        |           | allocate a block sized    |         |
|                        |           | zero bytes, rather than   |         |
|                        |           | passing the request to    |         |
|                        |           | the standard library      |         |
|                        |           | allocation function. It   |         |
|                        |           | is recommended to have    |         |
|                        |           | this option enabled, and  |         |
|                        |           | it is by default.         |         |
+------------------------+-----------+---------------------------+---------+
            +--------------------------------------------------+
            | 4.5 Options concerning the layout of the logfile |
            +--------------------------------------------------+
There are also a couple of options that controls the layout of the logfile,
they are listed here.

+--------------+---------+---------------------------------------+---------+
| Option Name  | Type    | Description                           | Default |
+--------------+---------+---------------------------------------+---------+
| ShowLogs     | Boolean | With this option enabled all normal   | True    |
|              |         | log messages (successful operations)  |         |
|              |         | will be written to the logfile, if    |         |
|              |         | it's disabled no normal log messages  |         |
|              |         | will be written to the logfile.       |         |
|              |         | (This can be overridden by function   |         |
|              |         | calls, see the Function Reference).   |         |
+--------------+---------+---------------------------------------+---------+
| ExtraNewline | Boolean | If this option is enabled, there      | True    |
|              |         | will be an extra newline written to   |         |
|              |         | the logfile, between each             |         |
|              |         | log/warning message. This will make   |         |
|              |         | the logfile more readable.            |         |
+--------------+---------+---------------------------------------+---------+
| WordWrap     | Boolean | This option defines wether or not     | True    |
|              |         | the logfile should be word-wrapped.   |         |
+--------------+---------+---------------------------------------+---------+
----------------------------------------------------------------------------
                          +-----------------------+
                          | 5. Function Reference |
                          +-----------------------+
5.1 General information
5.2 Reference

                        +-------------------------+
                        | 5.1 General information |
                        +-------------------------+
MSS provides a number of functions, that either controls the behaviour of
MSS or outputs some information to the logfile. All calls are made through
macros, and all of these macros expand to nothing if the symbol `MSS' was
not defined, which is useful for switching between "debug" and "release"
mode when compiling your program. (Don't forget not to link the mss library
with your program if you are using C++ and want to test a "release" version
of your program).

Note that the MSS macros should not have any parenthesis after them in case
the function takes no arguments. See this example:

                    +-----------------------------------+
                    | char *ptr = new char[10];         |
                    | strcpy(ptr, "Hello");             |
                    | MSS_DISABLE_LOG_OUTPUT;           |
                    | MSS_REGISTER_CONSTANT_BLOCK(ptr); |
                    | MSS_ENABLE_LOG_OUTPUT;            |
                    | ...                               |
                    +-----------------------------------+
As you see the `MSS_DISABLE_LOG_OUTPUT' macro is called without any
trailing empty parenthesis ().

                              +---------------+
                              | 5.2 Reference |
                              +---------------+
This is the MSS function reference. (Actually macro reference, but all
macros call functions so...)

Functions macros that returns nothing and prints all output to the logfile
+------------------------------------+-------------------------------------+
| Function name                      | Description                         |
+------------------------------------+-------------------------------------+
| MSS_LOG_INFO                       | This command writes general info    |
|                                    | about the present memory state to   |
|                                    | the logfile. The info written is:   |
|                                    |                                     |
|                                    | ----------------------------------- |
|                                    | * The number of blocks currently    |
|                                    | allocated                           |
|                                    | ----------------------------------- |
|                                    | * The amount of memory currently    |
|                                    | used                                |
|                                    | ----------------------------------- |
|                                    | * The maximum amount of memory      |
|                                    | used since program start            |
|                                    | ----------------------------------- |
|                                    | * The number of calls to            |
|                                    | allocation/deallocation functions.  |
|                                    | ----------------------------------- |
|                                    | * The number of successful          |
|                                    | allocations/deallocations.          |
|                                    |                                     |
|                                    | Please note that all memory         |
|                                    | references done by MSS are about    |
|                                    | dynamically allocated memory, MSS   |
|                                    | does not proccess static or         |
|                                    | automatic memory usage.             |
+------------------------------------+-------------------------------------+
| MSS_LOG_INTERNAL_INFO              | This command lists some             |
|                                    | information about how much memory   |
|                                    | MSS actually uses, how much memory  |
|                                    | is wasted by the `WatchLimits'      |
|                                    | option and so on, to the logfile.   |
|                                    | It is not really useful for         |
|                                    | program debugging, but it's there   |
|                                    | in case you want to know anyway.    |
+------------------------------------+-------------------------------------+
| MSS_LOG_BLOCK_LIST                 | This command outputs a list of all  |
|                                    | currently allocated blocks to the   |
|                                    | logfile, together with information  |
|                                    | about where that block was          |
|                                    | allocated, by what function, the    |
|                                    | size of it and so on. A little      |
|                                    | warning is probably in place        |
|                                    | though, the output can be quite     |
|                                    | long if there is a lot of blocks    |
|                                    | allocated. (Just look at the test   |
|                                    | programs).                          |
+------------------------------------+-------------------------------------+
| MSS_LOG_BLOCK_LIST_FILTERED(func)  | This command iterates through the   |
|                                    | list of currently allocated         |
|                                    | blocks, and calls a user-supplied   |
|                                    | callback function for each block.   |
|                                    | This allows for selective           |
|                                    | inspection of block contents or     |
|                                    | selective block lists. The          |
|                                    | user-supplied callback function     |
|                                    | must be of the following type: int  |
|                                    | callback_func(char *out, void       |
|                                    | *block, unsigned int size, const    |
|                                    | char *label, const char *file,      |
|                                    | const char *function, unsigned int  |
|                                    | line); where block is a pointer to  |
|                                    | the block, size is the size of the  |
|                                    | block, label is a string            |
|                                    | containing the label of the block   |
|                                    | if any has been set, or NULL        |
|                                    | otherwise, file, function, line     |
|                                    | represents the file, line and       |
|                                    | function in which the block was     |
|                                    | allocated. (The function might not  |
|                                    | be correct if your compiler does    |
|                                    | not support a FUNCTION macro).      |
|                                    | All the output of this function     |
|                                    | that you want written to the        |
|                                    | logfile should be written into out  |
|                                    | which points to an empty string.    |
|                                    | (see Sample 2 for an example).      |
|                                    |                                     |
|                                    | Exactly what the callback function  |
|                                    | does is not relevant as long as:    |
|                                    |                                     |
|                                    | ----------------------------------- |
|                                    | * it does not alter the data        |
|                                    | passed to it (except for out)       |
|                                    | ----------------------------------- |
|                                    | * it does not write more than 1023  |
|                                    | characters to out                   |
+------------------------------------+-------------------------------------+
| MSS_CHECK_ALL_BLOCKS               | This command checks all allocated   |
|                                    | blocks for out-of-bound writings    |
|                                    | and corrupted constant blocks.      |
|                                    | This command is only effective if   |
|                                    | MSS was compiled with the           |
|                                    | WatchLimits option enabled (see     |
|                                    | Configuring MSS).                   |
+------------------------------------+-------------------------------------+
| MSS_CHECK_BLOCK_AT(ptr)            | This command checks the specified   |
|                                    | block starting at `ptr' for         |
|                                    | out-of-bound writings and if block  |
|                                    | was registered at constant also     |
|                                    | for corruption. This command is     |
|                                    | only effective if MSS was compiled  |
|                                    | with the WatchLimits option         |
|                                    | enabled (see Configuring MSS).      |
+------------------------------------+-------------------------------------+
| MSS_CHECK_POINTER_VALIDITY(ptr)    | This command tells you if the       |
|                                    | specified pointer `ptr' points to   |
|                                    | a legal (dynamically allocated)     |
|                                    | block of memory (not only the       |
|                                    | start of the block, but anywhere    |
|                                    | in a block). If not this command    |
|                                    | will write the nearest block start  |
|                                    | and block end, and the distance     |
|                                    | (in bytes) from the pointer to      |
|                                    | both start and end to the logfile.  |
+------------------------------------+-------------------------------------+
| MSS_LOG_MSG(str)                   | This command simply writes the      |
|                                    | specified string `str' to the       |
|                                    | logfile.                            |
+------------------------------------+-------------------------------------+
| MSS_DISABLE_LOG_OUTPUT             | Disabling log-output prevents all   |
| MSS_ENABLE_LOG_OUTPUT              | legal allocation or deallocation    |
|                                    | messages to be written to the log   |
|                                    | file. They are processed by MSS,    |
|                                    | but silently. Warnings and command  |
|                                    | outputs are still written anyway.   |
+------------------------------------+-------------------------------------+
| MSS_LOG_MSG(str)                   | This command simply writes the      |
|                                    | specified string `str' to the       |
|                                    | logfile.                            |
+------------------------------------+-------------------------------------+
| MSS_STARTUP                        | This command initializes MSS. It    |
|                                    | is good practice to use this in     |
|                                    | the very beginning of your          |
|                                    | program, however not neccessary.    |
|                                    | If you are registering a function   |
|                                    | with atexit() before doing any      |
|                                    | memory allocations though, it is    |
|                                    | strongly recommended that you put   |
|                                    | this command before the call to     |
|                                    | atexit.                             |
+------------------------------------+-------------------------------------+
| MSS_SET_BLOCK_LABEL(ptr, str)      | This command will give the block    |
|                                    | pointed to by `ptr' the label       |
|                                    | specified by `str'. This label      |
|                                    | will then be written to the         |
|                                    | logfile whenever a warning/message  |
|                                    | is written that involves this       |
|                                    | pointer. This is useful for         |
|                                    | keeping track of pointers.          |
+------------------------------------+-------------------------------------+
| MSS_DUMP_BLOCK(ptr, filename)      | This command will generate a raw    |
|                                    | binary dump of the memory contents  |
|                                    | pointed to by `ptr' and write it    |
|                                    | to the file specified by            |
|                                    | `filename'.                         |
+------------------------------------+-------------------------------------+
| MSS_REGISTER_CONSTANT_BLOCK(ptr)   | These commands                      |
| MSS_UNREGISTER_CONSTANT_BLOCK(ptr) | registers/unregisters the block     |
|                                    | starting at `ptr', as a constant    |
|                                    | block. When a block is registered   |
|                                    | as constant it means that the       |
|                                    | contents of that block may not be   |
|                                    | changed, and MSS will print a       |
|                                    | warning if they are, the next time  |
|                                    | this block is checked. This         |
|                                    | function uses a very simple         |
|                                    | checksum method, that simply adds   |
|                                    | all the bytes in the block          |
|                                    | together. This is not very bullet   |
|                                    | proof, but the chance is pretty     |
|                                    | big that a bug will be detected by  |
|                                    | this method.                        |
+------------------------------------+-------------------------------------+
| MSS_ENTER_SCOPE                    | These commands are useful, if you   |
| MSS_LEAVE_SCOPE                    | want to make sure that all blocks   |
|                                    | that are allocated within a scope   |
|                                    | are deallocated at the end of that  |
|                                    | scope. Simply enclose the scope     |
|                                    | you want to check with              |
|                                    | `MSS_ENTER_SCOPE;' at the top and   |
|                                    | `MSS_LEAVE_SCOPE;' at the end.      |
|                                    |                                     |
|                                    | (This function only checks the      |
|                                    | number of allocated blocks, so it   |
|                                    | might fail to detect a bug the way  |
|                                    | you want it, however this should    |
|                                    | be quite unlikely).                 |
|                                    |                                     |
|                                    | A warning will be printed at the    |
|                                    | termination of the program (or      |
|                                    | what MSS believes is the            |
|                                    | termination of the program anyway)  |
|                                    | if the number of MSS_ENTER_SCOPE's  |
|                                    | don't match the number of           |
|                                    | MSS_LEAVE_SCOPE's executed.         |
+------------------------------------+-------------------------------------+

Functions macros that returns a value (`unsigned int') to the caller and
prints nothing to the logfile
+--------------------------------+-----------------------------------------+
| Function name                  | Description                             |
+--------------------------------+-----------------------------------------+
| MSS_CURRENTLY_USED_MEM         | Returns the amount of currently         |
|                                | allocated memory, not including the     |
|                                | extra memory wasted by MSS internally.  |
+--------------------------------+-----------------------------------------+
| MSS_MAXIMUM_USED_MEM           | Returns the maximum amount of           |
|                                | allocated memory since program start,   |
|                                | not including the extra memory wasted   |
|                                | by MSS internally.                      |
+--------------------------------+-----------------------------------------+
| MSS_NUMBER_OF_ALLOCATED_BLOCKS | Returns the number of allocated blocks. |
+--------------------------------+-----------------------------------------+

----------------------------------------------------------------------------
                                +-----------+
                                | 6.History |
                                +-----------+
6.1 The birth of MSS
6.2 Changelog
6.3 To-Do

                          +----------------------+
                          | 6.1 The birth of MSS |
                          +----------------------+
MSS was born, just like a lot of other programs, as a private tool created
by Juanje to check the dynamic memory activities of a game he's writing.
The game was growing, and he was feeling a little lost in a forest of
allocations/deallocations. At first it was only an overload of the C++
oprators `new' and `delete' that counted the amount of memory used. Then,
he had the idea of upgrading it and adding some other features. By those
days, he found a similar program called FORTIFY. He took a look at it and
found it great. But it didn't work for him (why?). So he decided to create
MSS and improve it with some of the features found in FORTIFY. He did it in
a couple of days. It was August '97.

Then Peter discovered a bug, that MSS didn't detect memory activites that
occured before main, like in global object constructors. So he sat down and
fixed this in a couple of days, but the solution still wasn't good enough
he thought, so he decided to make a better solution by rewriting the entire
MSS in ANSI C. And after he did that he added some more features,
discovered some more bugs, and modified it all again, and spammed Juanje
with e-mails about all the things he had done, although he knew Juanje was
too busy with his exams to even check his mailbox! After he had done all
that, he decided to rewrite the documentation, since so many changes were
made... It was January '98, and MSS did not look anything like the first
betas that Juanje first released.

Finally, Peter and Juanje started working together on MSS, hardtesting it
and adding new features, preparing the first real release of MSS, it is
February '98.

Then Juanje got too many other things to attend to, to continue the
development of MSS. Peter worked for a couple of weeks, but then he too
could not work with MSS anymore. So there was version 1.1 lying on Peter's
HDD without being released until August '98. Now Peter got a mail from a
guy with a question about MSS, and he decided to release the new version of
MSS, version 1.1.

                              +---------------+
                              | 6.2 Changelog |
                              +---------------+
Version 0.90Beta

First public release: It was called SENTINEL, but there is a commercial
product with this same name, so it had to be changed. Sorry if this caused
any confussion or inconvenience.

Version 0.91Beta

September 97:

  * Changed name to "MSS".
  * Corrected a bug related to NULL pointer deallocation (Thanks to Miguel
    Murillo :)
  * Added new functions: CHECK_POINTER, LOG_MSG.
  * Corrected/updated documentation.

Version 0.92Beta

October 97:
  * Added FINISH_MEM feature.

Version 0.93Beta

November 97:

  * Corrected a bug that caused a GPF when deallocating a NULL pointer.
    Thanks to Przemyslaw G. Gawronski for reporting this bug.
  * Corrected a misfunction when linking pre-compiled modules. Thanks to
    Przemyslaw G. Gawronski for reporting this bug.
  * Corrected/updated documentation. (Re-read!)

Version 0.95Beta (never released)

December 98:

  * Support for malloc() and free() added, as MSS was rewritten in C by
    Peter.
  * The problem with allocations before main() not being detected by MSS
    was fixed.
  * Some bugs were fixed.
  * Added the possibility to log to either stdout or a user selectable
    logfile.
  * Added the 'MSS_' prefix to all global functions in mss.c and
    cppspec.cc, and also the #defines in 'use_mss.h'.
  * Changed the remaining Spanish variable names into english... Phew,
    finally something one can understand!

Version 0.96.2Beta (never released)

January 98:

  * Added support for realloc() and calloc().
  * Added MALLOC_FAIL_PERCENTAGE.
  * Added CHECK_ALL_ON_MALLOC
  * Added MSS_DISABLE_THREADING and MSS_ENABLE_THREADING to make MSS
    multi-threading safe.
  * Fixed a bug, which made new return NULL upon out-of-memory error.
  * Added a feature, so that warnings were printed when trying to free()
    memory which was allocated by 'new' and vice versa.
  * Added MSS_WORD_WRAP_LOG_FILE.
  * Added MSS_ENTER_SCOPE, MSS_LEAVE_SCOPE
  * Added logging possibilities to stderr.
  * Made MSS ANSI C/C++ compliant(?). (It compiles okay with '-Wall -W
    -ansi -pedantic' on GCC anyway :)
  * Removed the CHECK_CONSTANT_BLOCK command, since this is now covered by
    MSS_LOG_CHECK_BLOCK_AT().
  * Moved some stuff from 'mss.h' to 'config.h', to avoid any
    name-conflicts with the user's program. Now everything in 'mss.h' and
    'use_mss.h' starts with 'MSS_' or 'mss_'.

Version 0.96.3Beta (never released)

January 98:

  * Removed the 'use_mss.h' file, and put everything in 'mss.h'.
  * Added support for a Special Logfile, to be used by the post-mortem
    program.
  * Tidied up the code a bit.
  * Fixed a bug generating a SIGSEGV sometimes when writing the logfile to
    a file. (How did this go by unnoticed anyway by the way).
  * Fixed a bug with the internal function check_if_initialized().
  * Added a crappy makefile for Microsoft Visual C++ 1.5.

Version 1.0Beta

February 98:

  * Fixed a bug related to MSS prematurely exiting the program.
  * Dumped `config.h', and added support for run-time configuration files.
  * Rewrote the documentation in HTML... (time-consuming)
  * Split MSS up into several source files, rewriting lots of stuff
  * Added support for new[], delete[], xmalloc(), xrealloc(), xfree(),
    cfree() and strdup().
  * Added MSS_SET_BLOCK_LABEL()
  * Added MSS_DUMP_BLOCK()
  * Added some new configuration options
  * Fixed a lot of minor/major bugs that noone remembers

Version 1.1

April 98:

  * Fixed a bug related to diffrent pointer size of diffrent platforms.
    (MSS_PTR_SIZE_T and MSS_PRINTF_SIZE_T was added).
  * MSS now shows both the number of times an allocation/deallocation
    function was successfully executed and the number of times it was
    called.
  * MSS now reports the size of a block being deallocated.
  * You can now use hexadecimal numbers in the config files too.
  * Fixed a bug in the pointer validity check. Wrong distance to nearest
    block was reported.
  * Fixed a layout bug in the pointer validity check.
  * Corrected some things in the documentation, and added some new
    information
  * Added a config options to disable/enable normal log output
  * Added a new function, MSS_LOG_BLOCK_LIST_FILTERED, thanks to Olaf
    Stoyke for contributing with this function.

Version 1.2 (current version, only minor updates)

November 98:

  * Fixed a couple of lines not conforming to the ANSI C standard.
  * Included a project file and documentation on how to compile and install
    MSS using Borland C++ 5.02. Thanx to Rolf F. Katzenberger for spending
    time doing this and sending the results to me (Peter).

                                +-----------+
                                | 6.3 To-Do |
                                +-----------+
We are working our way down the To-do list, and not many things are here
right now. If you are missing some feature in MSS and you can't find it in
this list, please send us a comment. Any suggestions are appreciated.

  * A post-mortem program that analyzes log file and tells you valuable
    info like bugs found, statistics and so... (There is some not even
    nearly finished stuff calling itself MSLAP, but it doesn't do very much
    at all yet).
  * Better thread-safety, the one in this version is untested, so if you
    have any experience of this, please report it.
  * Monitoring of deallocated memory
  * Better Sample programs... (You can help with this, please send any
    contributions to us!)
  * Better looking and tidy code
  * Better code ;)

----------------------------------------------------------------------------
                        +---------------------------+
                        | 7. Contacting the authors |
                        +---------------------------+
7.1 General info
7.2 Submitting a bug-report

                            +------------------+
                            | 7.1 General info |
                            +------------------+
MSS was written by Juan Jesus Alcolea Picazo, a920101@zipi.fi.upm.es and
Peter Palotas, blizzar@hem1.passagen.se

Any comments, suggestions and bugreports are very welcome. Please direct
all such e-mails to Peter, since Juan are not currently working on MSS.

                      +-----------------------------+
                      | 7.2 Submitting a bug-report |
                      +-----------------------------+
If you are going to submit a bug report, the best thing you can do is to
send us the logfile and the smallest source code possible to reproduce the
bug. The second best thing to do is to send us the entire source-code to
your program (if the source < 50K). If the source code is large or you
don't want to send it to us by some other reason, just send us the logfile
and we'll see what we can do.

And ofcourse, tell us what the problem is and what version of MSS you are
using!

----------------------------------------------------------------------------
                              +--------------+
                              | 8. Copyright |
                              +--------------+
+--------------------------------------------------------------------------+
| MSS -- Memory Supervision System version 1.2 Copyright (c) 1998 Juan     |
| Jesus                                                                    |
| Alcolea Picazo and Peter Palotas                                         |
|                                                                          |
| This program is free software; you can redistribute it and/or modify it  |
| under the terms of the GNU General Public License as published by the    |
| Free Software Foundation; either version 2 of the License, or (at your   |
| option) any later version.                                               |
|                                                                          |
| This program is distributed in the hope that it will be useful, but      |
| WITHOUT ANY WARRANTY; without even the implied warranty of               |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU         |
| General Public License for more details.                                 |
|                                                                          |
| You should have received a copy of the GNU General Public License along  |
| with this program; if not, write to the Free Software Foundation, Inc.,  |
| 675 Mass Ave, Cambridge, MA 02139, USA.                                  |
| (See also Contacting the Authors).                                       |
+--------------------------------------------------------------------------+
