Unit MemCheck |
MemCheck: the ultimate memory troubles hunter Created by: Jean Marc Eber & Vincent Mahon, SociÊtÊ GÊnÊrale/MARC/SGOP/R&D Version 1.30 Changes: *** 23 February 1998 MemCheckLogFileName is an exported variable, so you can set it at run-time *** 20 February 1998 New option: CheckHeapStatus At the end of each call to the memory manager, we get the heap status At each entry into a method of the memory manager, we verify that the heap status has not changed (the contrary would mean something has gone bad and has corrupted the memory). When this options is turned ON, the rest of MemCheck is disabled. It is then impossible to hunt memory leaks. You have to choose ! Warning: this is VERY VERY time consuming *** 15 January 1998 New option: IdentifyObjectFields, which attempts an improved reporting which specifies "object dummy is never destroyed and was likely to be in 3rd field of object ..." *** 04 December 1997 MemCheck now correctly raises EOutOfMemory when no more memory is available from the system. Documentation slightly improved. *** 18 September 1997 Works on Delphi 3 (build 5.53), under Windows NT (should work on Win 95, but this was not tested). This unit is used in real work conditions at SociÊtÊ GÊnÊrale, on the Opt'It project (> 400000 lines of code). We have to say it was undocumented until recently (used internaly only), so the doc (the comments you are reading) is likely to contain errors, and is definitely incomplete. Feel free to contact us for more information. You'll notice MemCheck does not have a nice interface, but this is not our aim. The role of MemCheck is to be an efficient and reliable tool; we do not have a lot of time to make it cute to the end user (don't forget it is a debugging tool). Contact... Jean Marc Eber is at: Jean-Marc.Eber@socgen.com Vincent Mahon is at: Vincent.Mahon@socgen.com Our address is: Tour SociÊtÊ GÊnÊrale Marc/Sgop/R&D 92987 Paris - La DÊfense cedex France Copyrights... The authors grant you the right to modify/change the source code as long as the original authors are mentionned. Please let us know if you make any improvements, so that we can keep an up to date version. We also welcome all comments, preferably by email. Disclaimer... You use MemCheck at your own risks. This means that you cannot hold the authors or SociÊtÊ GÊnÊrale to be responsible for any software\hardware problems you may encounter while using this module. General information... MemCheck replaces Delphi's memory manager with a home made one. This one logs information each time memory is allocated, reallocated or freed. When the program ends, information about memory problems is provided in a log file and exceptions are raised at problematic points. Basic use... Set the MemCheckLogFileName option. Call MemChk when you want to start the memory monitoring. Nothing else to do ! When your program terminates and the finalization is executed, MemCheck will report the problems. This is the behaviour you'll obtain if you change no option in MemCheck. Features... - List of memory spaces not deallocated, and raising of EMemoryLeak exception at the exact place in the source code - Call stack at allocation time. User chooses to see or not to see this call stack at run time (using ShowCallStack), when a EMemoryLeak is raised. - Tracking of virtual method calls after object's destruction (we change the VMT of objects when they are destroyed) - Tracking of method calls on an interface while the object attached to the interface has been destroyed - Checking of writes beyond end of allocated blocks (we put a marker at the end of a block on allocation) - Fill freed block with a byte (this allows for example to set fields of classes to Nil, or buffers to $FF, or whatever) - Detect writes in deallocated blocks (we do this by not really deallocating block, and checking them on end - this can be time consuming) - Statistics collection about objects allocation (how many objects of a given class are created ?) - Time stamps can be indicated and will appear in the output Options and parameters... - You can specify the log files names (MemCheckLogFileName) - It is possible to tell MemCheck that you are instanciating an object in a special way - See doc for CheckForceAllocatedType - Clients can specify the depth of the call stack they want to store (StoredCallStackDepth) Warnings... - MemCheck is based on a lot of low-level hacks. Some parts of it will not work on other versions of Delphi without being revisited (as soon as System has been recompiled, MemCheck is very likely to behave strangely, because for example the address of InitContext will be bad). - As leaks are reported on end of execution (finalization of this unit), we need as many finalizations to occur before memcheck's, so that if so memory is freed in these finalizations, it is not reported as leak. In order to finalize MemCheck as late as possible, we use a trick to change the order of the list of finalizations. After MemCheck are finalized only SysUtils, System and SysInit. This implies that we must not use any other unit which has a finalization. For example, we can not use the unit classes, so we have to implement our own lists and string lists here. Other memory managing products which are available (found easily on the internet) do not have this problem because they just rely on putting the unit first in the DPR; but they report incorrect leaks ! MemCheck does not, as far as we know. - Some debugging tools exploit the map file to return source location information. We chose not to do that, because we think the way MemCheck raises exceptions at the good places is better. It is still possible to use "find error" in Delphi. - Memcheck is not able to report accurate call stack information about a leak of a class which does not redefine its constructor. For example, if an instance of TStringList is never deallocated, the call stack MemCheck will report is not very complete. However, the leak is correctly reported by MemCheck.
Classes |
Functions |
AddTimeStampInformation - really releases the blocks
step 6: we save and show the output
BlockAllocationAddress - Is the given block bad ?
P is a block you may for example have created with GetMem, or P can be an object.
CommitReleases - Outputs the blocks allocated
this is not a leak
IsMemCheckActive - The address at which P was allocated
If MemCheck was not running when P was allocated (ie we do not find our magic number), we return $00000000
not installed yet ?
LogSevereExceptions - Logs the given information as associated with the current time stamp
Requires that MemCheck is active
The closing of the file is done in the finalization
MemChk - bring MemCheck to its new pos
MemoryBlockCorrupted - Activates the exception logger
OutputAllocatedBlocks - sets back the memory manager that was installed before MemChk was called
If MemCheck is not active, this does not matter.
UnMemChk - Activates MemCheck and resets the allocated blocks stack.
Types |
Constants |
Variables |
Functions |
step 6: we save and show the output
mettre dans ESI l'adresse du dÊbut de MyInterfaceVMT: correct ?????
The closing of the file is done in the finalization
Types |
Constants |
Variables |