SourceForge.net Logo Main page Documentation Download Development SourceForge project page


Node:Top

MSS

Memory Supervision System (MSS) is a C/C++ library for detecting dynamic memory allocation bugs.


Node:Introduction, Next:, Previous:Top, Up:Top

Introduction


Node:What is MSS, Next:, Up:Introduction

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 C/C++ library that helps you in the notorious 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:

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:

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


Node:How does it work, Next:, Previous:What is MSS, Up:Introduction

How does it work

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.


Node:Compiler compatibility, Next:, Previous:How does it work, Up:Introduction

Compiler compatibility

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, there are a lot of different 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, EGCS 1.1 and GCC 2.95.3 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.


Node:Where is MSS available, Previous:Compiler compatibility, Up:Introduction

Where is MSS available

The information on where to get the latest version of MSS is available at http://libmss.sourceforge.net.


Node:Compiling and installing, Next:, Previous:Introduction, Up:Top

Compiling and installing


Node:Unpacking the package, Next:, Up:Compiling and installing

Unpacking the package

You have to unpack the archive preserving the directory structure. Depending on your platform there are different ways 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.

MSS will unzip itself into its own directory, ./mss12/, so there is no need to create a separate directory for MSS before unzipping the archive.


Node:Configuring MSS for your compiler, Next:, Previous:Unpacking the package, Up:Compiling and installing

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 specifier string constant that will make printf() correctly print an argument of type MSS_PTR_SIZE_T. For example, 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 some string constant in case your compiler doesn't provide such a macro, for example "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 need 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 toggling this, that should help. (GCC 2.8.0 and latter support exceptions and want this enabled, earlier versions do not). 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 severe error or crash.
MSS_DISABLE_THREADING_FUNC MSS_ENABLE_THREADING_FUNC
These options must be defined. They are 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.


Node:Configuring and installing MSS using GCC, Next:, Previous:Configuring MSS for your compiler, Up:Compiling and installing

Configuring and installing MSS using GCC

Since MSS was developed using GCC, and comes with a makefile for GCC, there should not be any problems, unless you use a really old version of GCC. In this case you may need to tweak mss.h as described in previous section. See Configuring MSS for your compiler.

If you have GCC but not G++, the GNU C++ compiler, you will want to uncomment the 'NOCPP=.' line in the makefile.

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

Just enter make install, if you want to install the package to its default locations, which are:

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

If you are using G++ 2.95.x or later, you have to replace header file <streambuf.h> because of incompatibility See Known problems with MSS. For DJGPP, just copy %DJDIR%/contrib/mss/streambuf.h to %DJDIR%/lang/cxx/streambuf.h.

There are a few more rules in this makefile:

make all
This will compile everything (the library and the sample programs). The library will be placed in lib/[linux|djgpp]/libmss.a, and the sample programs will be in the samples directory.
make lib
This will compile just the library.
make test
This will compile the test programs.
make install
This will install the library to /usr/local/lib/libmss.a under linux, or %DJDIR%/lib/libmss.a under DJGPP, and the header file 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.
make clean
This will remove all object files for the specific environment, i.e. if make clean is run under Linux it won't remove the DJGPP object files, and vice versa.
cleanall
This will remove all rebuildable files.
make uninstall
This will remove all installed files.


Node:Configuring and installing MSS using Borland C++ 5.02, Previous:Configuring and installing MSS using GCC, Up:Compiling and installing

Configuring and installing MSS using Borland C++ 5.02

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)". Also, if you are going to use MSS with multithreaded libraries, define MSS_DISABLE_THREADING_FUNC and MSS_ENABLE_THREADING_FUNC See Configuring MSS for your compiler.

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 MSS library, with debugging code
mss32MTdebug.lib
MSS 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

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.


Node:Using MSS, Next:, Previous:Compiling and installing, Up:Top

Using MSS


Node:How to make a program use MSS, Next:, Up:Using MSS

How to make a program use MSS

Making your program to use MSS is as we have mentioned earlier is 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 different 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/deallocations 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 make sure you have enough free disk space.


Node:Functions provided by MSS, Next:, Previous:How to make a program use MSS, Up:Using MSS

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. All functions are called through macros, which compile away to nothing in the case the preprocessor symbol MSS was not defined. This feature makes it easy to switch between "debug" and "release" mode.

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


Node:Warnings in logfiles, Next:, Previous:Functions provided by MSS, Up:Using MSS

Warnings in logfiles

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 block
There is no block allocated at the address that pointer points to. The main reasons for this are:
There is no block starting at 'address'
Same as above. This is issued when you request some info about a non existent block.
Pointer 'p' does not point to any valid memory
You are dealing with a pointer 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.
Zero length allocation
This warning does not indicate any bug by itself and thus it may be disabled. It warns about 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
This warning does not indicate any bug with current compilers and thus it may be disabled. Previously it was illegal to free pointer pointing to NULL. However, current C and C++ language standards permit this.


Node:Hints & tips, Next:, Previous:Warnings in logfiles, Up:Using MSS

Hints & tips


Node:Known problems with MSS, Previous:Hints & tips, Up:Using MSS

Known problems with MSS

Currently there is only one known serious problem with MSS: if your program overloads the operator new your program will not work correctly with MSS. For example, this happens with libstdc++ from GCC 2.95. (Workaround is described in installation instructions See Configuring and installing MSS using GCC. Also, if you make your own #define free <something> or any other allocation function, MSS will not work neither. Currently we have no good solution to these problems, but there is a workaround available: insert #include <no_mss.h> before any problematic place and re-include <mss.h> afterwards.


Node:Configuring MSS, Next:, Previous:Using MSS, Up:Top

Configuring MSS


Node:configure-info, Next:, Up:Configuring MSS

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 chapter about compiling and installing MSS using GCC (See Configuring and installing MSS using GCC, or in mss.h which is discussed in chapter on configuring MSS for your compiler (See Configuring MSS for your compiler.

All run-time specific configuration information is 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:

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.


Node:Configuration file syntax, Next:, Previous:configure-info, Up:Configuring MSS

Configuration file syntax

The purpose of the configuration files are to set various options to different 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 is expected for a particular option. 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"

The configuration files are case-insensitive, that is "LogFileName" is equal to "LOGFILENAME" and "logfilename".


Node:Specifying where to write logging output, Next:, Previous:Configuration file syntax, Up:Configuring MSS

Specifying where to write logging 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 will be sent in case both LogToStdout and LogToStderr are set to false. They are described below. mss.cfg
LogToStdout Boolean If this is set to true, logging output 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. False
LogToStderr Boolean If this is set to true logging output 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. False


Node:Options concerning error detection, Next:, Previous:Specifying where to write logging output, Up:Configuring MSS

Options concerning error detection

There is a number of options that lets you specify different methods which will either make MSS detect errors, either make it easier for the programmer to detect them. They are listed below:

Option name Type Description Default
WatchLimits Boolean This option 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 sentinel value. Then upon deallocation of the block, or upon request from user, this extra space is checked. If it doesn't 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. True
WatchSize Integer This option specifies 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. 32
WatchValue Integer (0-255) This option specifies 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. 0xA8
FillMemOnAlloc Boolean If this option is set to 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. True
FillMemOnAllocValue Integer (0-255) This option specifies the value for filling allocating memory with, if FillMemOnAlloc is set. 0x98
FillMemOnDealloc Boolean If this option is 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. True
FillMemOnDeallocValue Integer (0-255) This option specifies the value with which to fill deallocated memory with, if FillMemOnDealloc is set. 0x86
CheckOnDealloc Boolean With this option enabled all blocks will be checked for out-of-bound writings and constant block corruption as they are deallocated. It is strongly recommended that you leave this enabled. True
CheckAllOnAlloc Boolean If this option is set to 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. False
AllocFails Integer (0-100) This option should be a number between 0 and 100, which indicates how often calls to malloc will fail, returning NULL. This is useful for stress-testing you application, to see if it can deal with out-of-memory situations. For example, if this is set to 50, malloc and its family will return NULL about every second time it was called (on average), even though they did not actually run out of memory. Set to 0 to disable. 0
ExitOnWarning Boolean If this option is enabled, MSS will terminate 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. False
WarnOnAllNULLDeallocs Boolean If this option is set to true, MSS will always warn you when trying to deallocate a NULL pointer. The reason this warning can be disabled, is because it is legal to deallocate a NULL pointer according to the ISO C and C++ standards. 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. True
ZeroLenAllocReturnNULL Boolean If this option is set to true, MSS will always return NULL if the user program tries to allocate a block sized 0 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. True


Node:Options concerning the layout of the logfile, Previous:Options concerning error detection, Up:Configuring MSS

Options concerning the layout of the logfile

There are also a few options that control the layout of the logfile, they are listed here.

ShowLogs Boolean With this option enabled, all normal 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 setting does not affect output by MSS function calls from user code. True
ExtraNewLine Boolean If this option is enabled, there will be an extra newline written to the logfile, between each log/warning message. This will make the logfile more readable. True
WordWrap Boolean This option defines if the logfile should be word-wrapped. True


Node:Function reference, Next:, Previous:Configuring MSS, Up:Top

Function reference


Node:function-info, Next:, Up:Function reference

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 make a "release" version of your program).

Note that the MSS macros should not have any parenthesis after them in the case the macro does not take anhy 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 can see, the MSS_DISABLE_LOG_OUTPUT macro is called without any trailing empty parenthesis ().


Node:Reference, Previous:function-info, Up:Function reference

Reference

This is the MSS function reference (Actually it is a macro reference, but all these macros are function-like)

MSS_LOG_INFO
This command writes general info about the present memory state to the logfile. The info written is:

Please note that all memory references done by MSS are about dynamically allocated memory, MSS does not work with static nor 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.
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.
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 represent 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).

The callback function should meet following requirements:


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.
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.
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 MSS_ENABLE_LOG_OUTPUT
Disabling log output prevents all legal allocation or deallocation messages to be written to the log file. They are processed by MSS, but silently. Warnings and command outputs are written anyway.
MSS_STARTUP
This command initializes MSS. It is good practice to use this in the very beginning of your program, however it is 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 tracking 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) MSS_UNREGISTER_CONSTANT_BLOCK(ptr)
These commands registers/unregisters the block starting at ptr, as a constant block. When a block is registered as a constant block, it means that the contents of that block may not be changed, and MSS will print a warning if they are, by the next time this block is checked. This function uses a very simple checksum method, that simply sums up all bytes in the block. This is not very bulletproof method, but it should be sufficient for bug detecting.
MSS_ENTER_SCOPE MSS_LEAVE_SCOPE
These commands are useful if you 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.

Function-like macros that returns a value (unsigned int) to the caller and prints nothing to the logfile

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.


Node:Development, Next:, Previous:Function reference, Up:Top

Development


Node:Contacting the authors, Next:, Up:Development

Contacting the authors

MSS was originally written by Juan Jesus Alcolea Picazo, a920101@zipi.fi.upm.es and Peter Palotas, blizzar@hem1.passagen.se. Currently they do not respond to e-mails, so Laurynas Biveinis (lauras@softhome.net) has taken over maintainership and set up project hosting at SourceForge (http://www.sourceforge.net. He will return the project to the original authors when/if one of them contacts him.

The best way to contact MSS developers is to send e-mail to libmss-devel@lists.sourceforge.net.

More information is available at the project home page (http://libmss.sourceforge.net).


Node:Submitting a bug report, Next:, Previous:Contacting the authors, Up:Development

Submitting a bug report

The best way to report a bug is to use bug tracking system at SourceForge (follow `bugs' link on http://sourceforge.net/projects/libmss).

However, if the bug is very minor or you're too lazy, then simply drop a line to libmss-devel@lists.sourceforge.net.


Node:Changes, Next:, Previous:Submitting a bug report, Up:Development

Changes

Version 1.3

In development:

Version 1.2.1

Released on October 2001:

Version 1.2

Released on November 1998:

Version 1.1

Released on April 1998:

Version 1.0 Beta

Released on February 1998:

Version 0.96.3 Beta

January 1998: (never released)

Version 0.96.2 Beta

January 1998: (never released)

Version 0.95 Beta

December 1997: (never released)

Version 0.93 Beta

November 1997:

Version 0.92 Beta

October 1997:

Version 0.91 Beta

September 1997:

Version 0.90 Beta

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.


Node:Todo, Next:, Previous:Changes, Up:Development

Todo

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.


Node:The birth of MSS, Previous:Todo, Up:Development

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.

In 2000 Laurynas Biveinis has found an incompatibility between MSS version 1.2 and GNU C++ compiler version 2.95 and set a workaround to Peter. But Peter replied that he would hand over maintenance of MSS if somebody comes up. In 2001, Laurynas has made a few bugfixes to MSS and wanted to publish them. However, this time both authors didn't reply to any mails, so Laurynas just went on and uploaded version 1.2.1 to SimtelNet.


Node:Concept index, Next:, Previous:Development, Up:Top

Concept index


Node:Function index, Next:, Previous:Concept index, Up:Top

Function index


Node:Copying, Previous:Function index, Up:Top

GNU GENERAL PUBLIC LICENSE

Version 2, June 1991

Copyright © 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

  1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".

    Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

  2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.

    You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

  3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
    1. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
    2. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
    3. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)

    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

    Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.

    In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

  4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
    1. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    2. Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    3. Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

    The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

    If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.

  5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
  6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
  7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
  8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

    If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.

    It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

    This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

  9. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
  10. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

    Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.

  11. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
  12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Appendix: How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

one line to give the program's name and a brief idea of what it does.
Copyright (C) yyyy  name of author

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

The hypothetical commands show w and show c should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than show w and show c; they could even be mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.

signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.