CreateMemDebug
Initializes memory debugging package.
Synopsis
Err CreateMemDebug(uint32 controlFlags, const TagArg *args);
Description
This function creates the needed data structures and initializes them as needed for memory debugging. This function actually only does anything if MEMDEBUG is defined, otherwise it is a NOP.
Memory debugging provides a general-purpose mechanism to track and validate all memory allocations done by an application. Using memory debugging, you can easily determine where memory leaks occur within a title, and find illegal uses of the memory subsystem.
To enable memory debugging in a title, do the following:
- Add a call to
CreateMemDebug()
as the first instruction in the main()
routine of your program.
- Add calls to
DumpMemDebug()
and DeleteMemDebug()
as the last instructions in the main()
routine of your program.
- Recompile your entire project with MEMDEBUG defined on the compiler's command-line (for the ARM compiler, this is done by adding _DMEMDEBUG).
- Link your code with memdebug.lib
With these steps taken, all memory allocations done by your program will be tracked, and specially managed. On exiting your program, any memory left allocated will be displayed to the console, along with the line number and source file where the memory was allocated from.
In addition, the memory debugging code makes sure that illegal or dangerous uses of memory are detected and flagged. Most messages generated by the debugging code indicate the offending source file and line within your source code where the problem originated.
When all options are turned on, the debugging code will check and report the following problems:
- memory allocations with a size of 0
- memory free with a bogus memory pointer
- memory free with a size not matching the size used when the memory was allocated
- NULL memory list passed to
AllocMemFromMemLists()
or FreeMemToMemLists()
- cookies on either side of all memory allocations are checked to make sure they are not altered from the time a memory allocation is made to the time the memory is released. This would indicate that something is writing beyond the bounds of allocated memory.
When MEMDEBUG is defined during compilation, all standard memory allocation calls are automatically vectored through the debugging code. This includes even memory allocation calls made inside of previously compiled.lib files you might be linking with. However, you can get better debugging information if you recompile everything in your project, including .lib files, with MEMDEBUG defined.
By calling the DumpMemDebug()
function at any time within your program, you can get a detailed listing of all memory currently allocated, showing from which source line and source file the allocation occurred.
Link order can be important when using memdebug.lib. The library should come before clib.lib, but after everything else. That is, the link order should be:
[many .lib files] memdebug.lib clib.lib
Arguments
- controlFlags
- A set of bit flags controlling various options of the memory debugging code.
- MEMDEBUGF_ALLOC_PATTERNS
- When this flag is specified, it instructs the debugging code to fill newly allocated memory with the constant MEMDEBUG_ALLOC_PATTERN. Doing so will likely cause your program to fail in some way if it tries to read newly allocated memory without first initializing it. Note that this option has no effect if memory is allocated using the MEMTYPE_FILL memory flag.
- MEMDEBUGF_FREE_PATTERNS
- When this flag is specified, it instructs the debugging code to fill memory that is being freed with the constant MEMDEBUG_FREE_PATTERN. Doing so will likely cause your program to fail in some way if it tries to read memory that has been freed.
- MEMDEBUG_PAD_COOKIES
- When this flag is specified, it causes the debugging code to put special memory cookies in the bytes before and 16 bytes after every block of memory it allocates. When a memory block is freed, the cookies are checked to make sure that they have not been altered. This option makes sure that your program is not writing outside the bounds of memory it allocates.
- MEMDEBUG_DEBUG_ON_ERRORS
- When this flag is specified, the debugging code will automatically invoke the debugger if any error is detected. Errors includes such things as mangled pad cookies, incorrect size for a FreeMem() call, etc. Normally, the debugging code simply prints out the error to the console and keeps executing.
- MEMDEBUG_ALLOW_OWNER_SWITCH
- This flag tells the memory debugging code that it is OK for memory to be allocated by one thread and freed by a different thread. Normally, this condition would be flagged as an error.
- MEMDEBUGF_CHECK_ALLOC_FAILURES
- When this flag is specified, the debugging code will emit a message whenever a memory allocation call fails due to lack of memory. This can be useful to track down where in a title memory is running out.
- MEMDEBUGF_KEEP_TASK_DATA
- The debugging code maintains some thread-specific statistics about memory allocations performed by that thread. This information gets displayed by DumpMemDebug(). Whenever all of the memory allocated by a thread is freed, the data structure holding the statistics for that thread automatically gets freed by the debugging code. This is undesirable if you wish to dump out statistics of the code just before a title exits. Specifying this flag causes the data structure not to be freed, making the statistical information available to DumpMemDebug().
- MEMDEBUGF_USE_VRAM
- The debugging code needs to allocate private memory to track information about every memory allocation call made. This flag tells the debugging code to allocate this private memory using MEMTYPE_VRAM instead of MEMTYPE_ANY. This is useful if you need as much DRAM as possible, and do not want the debugging code to take any away from you.
- args
- A pointer to an array of tag arguments containing extra data for this function. This must currently always be NULL.
Return Value
Returns > = 0 if successful or a negative error code. Current possible error codes are:
- MEMDEBUG_ERR_BADTAG
- An undefined tag was supplied. Currently the arg's parameter to this function should always be NULL.
- MEMDEBUG_ERR_BAD
- FLAGS
- An undefined flag bit was set in the control Flags parameter to this function.
Implementation
Library call implemented in memdebug.lib V24.
Associated Files
mem.h, memdebug.lib
Notes
You should make sure to turn off memory debugging prior to creating the final version of your program. Enabling memory debugging incurs an overhead of currently 32 bytes per allocation made. If you use the MEMDEBUGF_PAD_COOKIES option, this overhead grows to 64 bytes per allocation.
In addition, specifying the MEMDEBUGF_ALLOC_PATTERNS and MEMDEBUGF_FREE_PATTERNS options will slow down memory allocations and free operations, due to the extra work of filling the memory with the patterns.
When reporting errors to the console, the memory debugging subsystem will normally print the source file and line number where the error occurred. When using link libraries which have not been recompiled with MEMDEBUG defined, the memory debugging subsystem will still be able to track the allocations, but will not report the source file or line number where the error occurred. It will report < unknown source file > instead.
Caveat
If you link your program with memdebug.lib, you must call CreateMemDebug()
at the beginning of your program. Any attempt to allocate memory prior to calling CreateMemDebug()
will fail.
See Also
DeleteMemDebug
(), DumpMemDebug(), SanityCheckMemDebug()