In addition to the functions discussed in part1, Memory Validator provides explicit functionality for detecting Memory Corruption. When used with care, this functionality can allow you to identify memory corruption very quickly. When used carelessly, this functionality will be very slow, probably too slow to provide any meaningful results.
Using the Memory Corruption Detection tab on the setting dialog:
Your options should look like the image shown:
Using the Memory Corruption Filter tab on the setting dialog:
Your options should look like the image shown:
Using the options selected we will now perform a test which will identify a memory corruption. Based on the data shown, we will demonstrate how to isolate the error location to the line in which the error occurs without incurring a heavy performance penalty.
Step 1 focuses on a getting a broad brush picture of where the corruption happens in your application.
An example display is shown:
Using the information displayed you know that the data corruption happened between the last known good location and the location at which the memory was identifed as corrupt. The next process is to increase the frequency of the corruption checks whilst at the same time filtering the corruption checks so that corruption checks are only performed on likely parts of the application.
Step 2 repeats Step 1, but with specific focus on parts of the application. For our trivial application we can tell that the corruption seems to be associated with one specific C++ class, CTeststakView. The reason for this is that the memory allocated is managed by CTeststakView.
For your application, you may identify several classes which may be candidates for causing the memory corruption. Once you have identified the initial class candidates, you can enter these class names into the Memory Corruption Filter, as shown below. The callstacks for “allocation location”, “last know good” and “corrupted location” will give you clues as to which classes are appropriate for you to add the Memory Corruption Filter.
Note the changes to the filter shown above:
Combined with the tighter focusing of specific methods, we can increase the frequency at which checks are performed, as demonstrated by the new values shown in the Memory Corruption tab, shown below.
If we repeat the test run from Step 1, with the above settings, Memory Validator identifies the function corrupting memory and displays the data on the Memory tab.
In this example, we focused on the correct class and reduced the frequency to 1 very rapidly. However, the test application is not typical of a real application, it is smaller and less complex. In a real application you will need to refine you choice of filter classes and reduce the detection frequency number on each iteration until you identify the corrupting function.
Sensible choices of which classes (and methods – see the help file for how to filter on methods) to filter and how often to test should reduce the number iterations required to identify the memory corruption.
Typically when trying to detect memory corruption, once the corruption location is known, the test can stop. There is no value in closing the application normally as the application’s data is corrupt. Click the red X on the toolbar to kill the application immediately. Note that when killing the application this way, the session recorded by Memory Validator is discarded – be sure to make note of the information you need before killing the application this way.
If you choose to close the application normally be aware that this may take longer than usual because all the memory corruption hooks will still be installed and will be checking for memory corruption during your application’s shutdown period.
Finally, disable Memory Corruption Detection when you are finished using it.