This section details the requirements necessary to monitor C runtime (CRT) heap allocations, followed by sections specific to enabling debugging information for Visual Studio, C++ Builder, Delphi, MinGW, and other compilers.
If you are using Memory Validator to monitor C runtime (CRT) heap allocations, read on, and check you have the necessary run time library setup.
Once you're confident you have the required environment (CRT and debug info settings), skip to Quick Start.
The gist of the rest of this section is that Microsoft compiler users should use a dynamically linked CRT library, or you may use a statically linked CRT provided you have a matching MAP file.
Supported compilers and linkers
To track C runtime heap allocations, your program and/or dlls must be linked to the dynamic CRT in one of the following:
•MSVCRT.DLL
•MSVCRTD.DLL
•the equivalent depending on the version of Visual Studio e.g. msvcr70/71/80/90/100/110.dll
•an alternative library for other compilers, as outlined in the Memory Hooks reference
If you are linked statically, to one of the following CRTs:
•LIBC.LIB - single-threaded
•LIBCD.LIB - single-threaded debug
•LIBCMT.LIB - multi-threaded
•LIBCMTD.LIB - multi-threaded debug
then the CRT heap allocation tracking will function but performance will be slower than for the dynamically linked case.
However, in addition, you must generate MAP files for each EXE/DLL that you link statically to the C runtime. The MAP file should have the same name as the EXE/DLL but with the extension ".map", e.g. "example.dll" should have a corresponding MAP file "example.map".
What are MAP files and why are they needed? MAP files are typically plain text files that indicate the relative offsets of functions for a given version of a compiled binary. They contain information about your program’s global symbols, source file and source line numbers. In the event of statically linked CRT libraries, Memory Validator falls back to using the MAP file to locate the functions. You can create the MAP file when linking your executable or DLL by setting certain options for the linker. |
Why is dynamic linking better? The reason for this is that Memory Validator uses the Import Address Table to provide hooks into MSVCRT.DLL. When you link statically the Import Address Table is not present and cannot be hooked. Most large applications are dynamically linked (based on our testing), but many small projects are often built statically. These statically linked projects need to be built using the dynamic library for best monitoring performance. |
If using Borland compilers you can use Memory Validator to monitor memory allocations in a statically linked program. You'll be presented with the usual CRT warning dialog informing you that the use of the dynamic memory allocator could not be detected, but that can be ignored.
You can inspect (and change) the static/dynamic linking nature of your program:
Microsoft Developer Studio
Choose Project menu Settings... C++ tab on the dialog box Using the Category combo box choose Code Generation.
If you are using the dynamic multi-threaded MSVCRT.DLL the following will be shown in the Use run-time library combo box (highlighted in red below).
Alternatively, if using the debug MSVCRTD.DLL, the same box will show Debug Multithreaded DLL.
Visual Studio e.g. VS9.0 (2008)
Choose Project menu [ProgramName] Properties... Configuration Properties in the list C++ Code Generation
If you are using the debug dynamic multi-threaded MSVCRTD.DLL the following will be shown in the Runtime Library option (highlighted in red below).
Alternatively, if using the non debug MSVCRT.DLL, the same box will show Multi-threaded DLL (/MD).
The compiler options corresponding to the above choices are:
For dynamic multi-threaded CRT linking:
/MD |
MSVCRT.DLL |
/MDd |
MSVCRTD.DLL debug |
For static CRT linking:
/ML |
LIBC.LIB - single threaded |
/MLd |
LICD.LIB - single threaded debug |
/MT |
LIBCMT.LIB - multi-threaded |
/MTd |
LIBCMTD.LIB - multi-threaded debug |
To use dynamic linking you need to either select one of the selections shown in the pictures above, or use the /MD or /MDd compiler flags instead of /ML, /MLd, /MT, /MTd.
The following shows which option you should use when changing compiler options:
static |
dynamic |
|
/ML |
/MD |
|
/MT |
/MD |
|
/MLd |
/MDd |
|
/MTd |
/MDd |
If you are linked statically, you only need to make this change once and rebuild the application. If you are linked dynamically you do not need to rebuild your application.
When rebuilding your DLL(s), you may get warning messages which refer to libraries used by the static linking which you are no longer using. This is caused by some default settings in your project. You can prevent these by disabling the linking of default libraries. You will then need to specify any libraries you require.
In Developer Studio, the image below shows the checkbox to select to prevent linking to the default libraries.
In Visual Studio 9.0 to show the same option:
Choose Project menu [ProgramName] Properties... Configuration Properties in the list Linker Input Ignore All Default Libraries
When Memory Validator launches an application it checks to determine if the application is using the dynamic C runtime library (or equivalent).
If the dynamic CRT cannot be detected, a warning dialog is displayed to the user:
Don't panic! It looks worrying, but it's not! It is just a warning. You can still launch your application with Memory Validator.
Many applications do not use the dynamic CRT in the main .EXE, but do use it in the DLLs used by the application. In this case, Memory Validator will monitor CRT allocations in the DLLs, and will monitor non-CRT allocations (handles and other memory types) in the .EXE and the DLLs.
Lucky users of Borland compilers can build their applications statically linked or dynamically linked - either will work.