A dynamic memory analysis and debugging tool to be used in conjuction with TotalView.
To use MemoryScape, the binary must be compiled with the debug output turned on, e.g.
gcc -g example.c -o myprogram
To use the MemoryScape debugging tools on multiprocess applications, please link with the following library:
mpicc -g -o foo foo.c -L$TOTALVIEW/lib/libdbfork_64
The following assumes knowledge of how to use and navigate within TotalView, which can be found here.
Once you have started TotalView you must select 'Enable memory debugging' on the initial setup window. Once you have, set your other parameters and options as normal and then press 'OK'.
After TotalView starts you want to select 'Debug -> Open MemoryScape' from the main window. A new window will pop up showing the main MemoryScape window. Click on the shield near the top, this will mark the beginning and end of the memory you allocate and enable, for example, array bounds checking.
Note: because of the way memory checking is implemented, array bounds checking is detected properly only on arrays allocated like this:
my_arr = (<arr_type>*)malloc(sizeof(<arr_type>) * <num_elements>);
Once this has been done you may close the MemoryScape window and run your program as you normally would with TotalView. During execution, if an array bounds error is encounterd you should see a window like this one pop up:
This shows exactly where in the program the error was encountered, allowing, for example, a break point to be placed and the indexing variable's value to be checked. You may also click on the 'Allocation/Deallocation Location' tabs to see where the memory was originally set aside or released. The 'Block Details' tab will allow you to examine the contents of the memory block at that point in time. Note: a bounds error will cause the program to halt, preventing the execution of any code beyond the point of error until the problem is resolved.
If your program is allowed to finish a window will appear notifying you that a process is about to end and prompting for what action should be taken. If you do not wish to check the memory state you may allow the process to simply exit. Otherwise click on 'View memory data' to see the state of your memory at this point. You may examine the memory at any point execution is halted at a break point by going to 'Debug -> Open MemoryScape'.
Next you will see a window prompting for which report you would like to see. We will only be looking at two types: Leak Detection and Heap Status.
First we select the 'Leak Detection' report and are taken to its menu.
Select 'Source report' and you should see a window like the one below. All information is arranged by process and shows the total number of bytes that have been lost as well as the total number of blocks. By expanding the lists we can see the individual blocks that have been lost. Clicking on a block will put block-specific information in the lower left window. Expanding that list out will allow you to see the source code surrounding where that block of memory was allocated.
Next lets look at the heap by selecting 'Heap Status' in the tool bar. Again we are presented a few options, selecting 'Source report' again we see a window like the following.
With 'Data Source -> Allocations' selected we can see all of the currently allocated memory, whether or not there happens to be anything pointing to it. By clicking on a specific block we can see the source code like before. If you want to see which blocks were properly deallocated, and where, you can change the 'Data Source' to 'Deallocations'. The window will change to one like below, and you will be able to examine these blocks the same as the others.
The above example was a very basic one, but should get you started being able to debug your programs. Once you feel comfortable using this tool I encourage you too visit the official website and obtain the user's guide to find usage of the more advanced tools.
Source for the above examples may be found here.
See the official website: MemoryScape
Documentation may be found at: