Introduction

MemPro
C++ Memory Profiler

Introduction

MemPro is a C++ MemPro profiler for Windows. MemPro can profile any application that has Windows compatible pdb files.

MemPro is a separate application that connects to the app being profiled using TCP and records information on all allocations and the entire state of memory.

In order to connect, the application being profiled needs to be compiled against the MemProLib code. This can be done by simply adding two lines of code to your main source code file. See the Quick Start page or the Setup page for more information.

Once connected MemPro will track all allocations and frees. At any time you can take a snapshot of the entire state of memory. These snapshots can then be viewed in a variety of ways.

MemPro is designed to be fast and efficient, and can cope with profiling massive applications with thousands of allocations per second.

Please see the Quick Start Guide for getting started with MemPro.

© Copyright 2011 - 2013 Stewart Lynch
slynch@puredevsoftware.com


Quick Start

Quick Start

This quick start guide is designed to get you up and running as quickly as possible.

1. Compile your app with MemProLib

Assuming you haven't overridden new/delete simply add these two lines to your main cpp file and add this path to your global paths: C:\Program Files\PureDevSoftware\MemPro\MemProLib

#define OVERRIDE_NEW_DELETE
#include "C:\Program Files\PureDevSoftware\MemPro\MemProLib\src\MemPro.cpp"

2. Connect to your app

Start MemPro and click on the Launch button. Enter the path to your exe

3. Take a snapshot

Click on the snapshot button (the one with the orange box)

4. View the snapshot

Click on the Call Tree button

You will now see the call tree view that shows a breakdown of all of the memory in your application and where it was allocated from.


Setup

Setup

To allow MemPro to connect with your application you must compile your app with the MemProLib code and call the tracking functions when allocating memory. There are three main ways you can do this:

  1. Include MemPro.cpp in one of your source cpp files
  2. Compile and Link against the MemProLib.lib
  3. Link with MemProDll.dll

The MemProLib library can be found in the source code installation folder that was set in the installation, the default is:
C:\Program Files\PureDevSoftware\MemPro

Note: if you are profiling an application with multiple dlls you must use option 3 and link MemProDll.dll.

1. Including MemPro.cpp

This is the recommended way of embedding the code. It is simple, and easy to comment out when not needed. It is also the most portable solution.

Add these three lines of code to your main cpp source file:

//#define WAIT_FOR_CONNECT true
#define OVERRIDE_NEW_DELETE
#include "MemPro.cpp"

(yes, you are including the cpp file)

the cpp file can be found here:
C:\Program Files\PureDevSoftware\MemPro\MemProLib\src

The WAIT_FOR_CONNECT line is optional. If defined to true your application will block on startup until MemPro has connected. This allows you to be sure that you are tracking every single allocation.

And that's it!

2. Linking to the MemProLib library

If you prefer to link to the MemPro library, include the MemPro.hpp in your main.cpp

//#define WAIT_FOR_CONNECT true
#define OVERRIDE_NEW_DELETE
#include "MemPro.hpp"

And link to one of the pre-built libraries in the lib folder.

The header file can be found here:
C:\Program Files\PureDevSoftware\MemPro\MemProLib\src

The lib files can be found here
C:\Program Files\PureDevSoftware\MemPro\MemProLib\lib

If none of the pre-built libraries are suitable you can build your own MemProLib from the source code in the src file. MemProLib builds on virtually any platform and OS. The MemProLib source code can be found here:
C:\Program Files\PureDevSoftware\MemPro\MemProLib\src

3. Linking to the MemProLib Dll

Add these two lines to a cpp source file in each dll that you want to profile

#define OVERRIDE_NEW_DELETE
Include "MemProDll.hpp"

Copy the MemProDLL.dll file to your exe directory.

The header file can be found here:
C:\Program Files\PureDevSoftware\MemPro\MemProDll\include

The dll and lib files are here:
C:\Program Files\PureDevSoftware\MemPro\MemProDll\bin

MemProDll.hpp includes a pragma telling the linker to link to MemProDll.lib. This adds a dependency to the dll. Please make sure the linker can find the lib file by adding the necessary path or modifying the pragma.

Note: Make sure that MemProDll.hpp is included only _once_ in each dll. Put it in the main source file, do not put it into a header that is included in multiple places.

Include and Library Paths

The installer automatically adds the include and library paths to the INCLUDE and LIB environment variables. However, the IDE does not use these variables unless run with the /useenv command line switch. So you'll probably want to add the path in the global property sheet in the IDE.

If you have already overridden new and delete

In the above solutions the OVERRIDE_NEW_DELETE define tells MemPro to override new and delete with its tracking hooks inserted. If you have already overridden new and delete (maybe for your own memory manager) you will need to insert the MemPro hooks into your overridden functions:

Include MemPro.cpp as before but don't define OVERRIDE_NEW_DELETE. Instead use the MemPro::TrackAlloc and MemPro::TrackFree functions

#include "MemPro.hpp" // or MemProDll.hpp if linking to MemProDll.dll

bool g_WaitForConnect = false;

void* operator new(size_t size)
{
void* p = YourInternalAlloc(size);
MemPro::TrackAlloc(p, size, g_WaitForConnect);
return p;
}

void operator delete(void* p)
{
MemPro::TrackFree(p, g_WaitForConnect);
YourInternalFree(p);
}

void* operator new[](size_t size)
{
void* p = YourInternalAlloc(size);
MemPro::TrackAlloc(p, size, g_WaitForConnect);
return p;
}

void operator delete[](void* p)
{
MemPro::TrackFree(p, g_WaitForConnect);
YourInternalFree(p);
}

The g_WaitForConnect bool specifies whether the call blocks until the MemPro app has connected. This is useful for making sure absolutely every allocation is being tracked.

What if I can't use a winsock connection in my app?

MemProLib uses a winsock TCP connection to communicate with MemPro. If for some reason this isn't possible in your application (no network connection for example) then you can still use MemPro.

Instead of connecting to your application over TCP you can tell MemProLib to write out a dump file of all allocations. This dump file can then be opened in MemPro and analyised just like any other mempro file. To enable allocation dumping uncomment this line in MemPro.hpp

//#define WRITE_DUMP _T("allocs.mempro_dump")

When this define is enabled the specified file will be created and all operations will be written to this file instead of being set over the network. The define also removes any dependency on windows sockets, so you should be able to use it in any environment. This file can get pretty big, so please ensure you have enough disk space.

Note: To avoid linker errors when overriding new/delete, make sure that MemPro.cpp is included before any system headers that also override new/delete. You may need to turn off any pre-compiled headers for that file. You may also need to do a full re-compile of your app to avoid multiple defined new and delete function warnings.

If you have any problems setting up MemProLib:

  • see the FAQ on the website http://www.puredevsoftware.com/mempro_faq.htm
  • email slynch@puredevsoftware.com


Toolbars

Toolbars

There are 5 toolbars in MemPro for frequently used features.

App | Buttons for launching and connecting to an application or process
Snapshot | Buttons for taking snapshots
Tools | General tools for manipulating snapshots and global views not related to snapshots.
Settings | Change the memory units, set the symbol paths and show the settings dialog


Side Panel

Side Panel

The side panel has three sections:

  • Real-time stats
  • Current Snapshot
  • Snapshot list view

Real-time stats

The real-time stats panel shows stats on the currently connected process. It shows the time the process has been running, and the amount of memory allocated. This updates in real-time.

Current Snapshot

This shows stats on the currently selected snapshot. To select a snapshot, click on it in the snapshot list view or in the graph view.

Snapshot List View

This shows all of the snapshots in the current session, listed in time order. To select a snapshot left click on it. To open a view on the snapshot right click to bring up the context menu.


Output Window

Output Window

The output window can be toggled from the View Menu. The output window will show the operations that MemPro is performing. It can be useful for tracking down why pdb files are not loading.

For a more detailed log see this file C:\Users\Stewart\AppData\Roaming\MemPro\MemPro.log.
If you submit a bug report you will usually need to supply this file.


Graph View

Graph View

Overview

The graph shows the amount of memory allocated over time. It updates in real-time while connected to the application.

Controls

Left click & drag | Scroll the time axis
Mouse Wheel | Zoom the time axis
Right Click | Open context menu where you can make a snapshot or change the graph settings
Right click and drag | Take two snapshots and subtract on from another. More info here

1. Check box keys | These check boxes show you the colours of the different memory states, and allows you to enable and disable from in the graph.
2. A snapshot | This is a snapshot that was taken. A yellow line shows that the snapshot is selected, red lines are unselected snapshots. Select a snapshot by clicking in it.
3. Allocated memory graph |
4. Allocation Sizes Graph | (read more below)

Graph Settings

Right click on the graph and select Settings from the context menu, or View Menu -> Graph -> Graph Settings

Auto Memory Range | MemPro will automatically scale the Memory axis to keep the graph in view
Min Memory | The minimum memory to display on the y axis (if Auto Memory Range is disabled)
Max Memory | The maximum memory to display on the y axis (if Auto Memory Range is disabled)
Timescale | The number of seconds to show on the time axis (zoom level)

Allocation Size Graph

The allocation size graph shows how many allocations of each size happen over a fixed interval, (100ms by default). The graph only updates while connected.

The light grey lines show the total number of allocations for each size. The yellow lines in front show the number of allocations of that size in the last interval.

To change the interval right click on the graph and select Settings. Here you can change time interval and the Count and Size axis limits.


App Toolbar

App Toolbar

Launch | Launches and connects to the current application. Use the '...' button to open the launch settings dialog.
Connect | Connects to an already running process. Use the '...' button to open the connection settings dialog.
Disconnect | Take a snapshot and disconnect from the current process. The process will not be terminated. Note that if the process terminates MemPro will automatically take a snapshot and disconnect.


Launch Dialog

Launch Dialog

This dialog allows you to set the path to the executable to launch, its command arguments and working directory. Hitting OK will launch the application. This information will be saved in the settings, so you only have to enter it once. The next time you want to start the app you can simply hit the Launch button.


Connect Dialog

Connect Dialog

Here you can set the IP address and port of the process that you want to connect to. To connect to a process on your local machine use localhost or 127.0.0.1

The port number must match the port in g_DefaultPort in MemProLib. The default is 27016. If this port clashes with another port change the port number here and in MemProLib.


Snapshot Toolbar

Snapshot Toolbar

The snapshot toolbar has two buttons, 'Snapshot' and 'Full Snapshot'. These buttons can be used while connected to a process to take a snapshot of the memory state at the current time.

Snapshot

Full Snapshot

Once a snapshot has been taken it will appear in the Snapshot list view in the side panel and as a red or yellow line in the graph view.

Snapshots can be selected by clicking on them in the side panel or in the graph view. A view can be opened on a snapshot using the Snapshot Views toolbar buttons or right clicking in the snapshot list view.
See Snapshot Views for more information.


Snapshot

Snapshot

Use this button to take a snapshot while the connected to a process. Once you have taken a snapshot you can open various views on the snapshot, read more...

What is a snapshot?

A snapshot is a copy of the current state of memory. A snapshot contains:

  • The state of all pages in the process
  • Information on how much memory is allocated
  • Information on all currently active allocations

Note that this standard snapshot does not contain the contents of memory. To capture the contents of memory use the Full Snapshot.

How to take a snapshot at a previous point in time?

Right click in the graph panel where you want to take the snapshot and click 'Take Snapshot'. This can be done connected or disconnected.


Full Snapshot

Full Snapshot

Use this button to take a snapshot while the connected to a process. Once you have taken a snapshot you can open various views on the snapshot.

What is a Full Snapshot?

A full snapshot is a copy of the current state of memory. A snapshot contains:

  • The state of all pages in the process
  • Information on how much memory is allocated
  • Information on all currently active allocations
  • The contents of the entire process memory

Full snapshots take much longer than standard snapshots and use up a lot more memory.

What is it useful for?

Full snapshots are useful when you want to view the contents of memory in the Memory View. They are also used to find unreferenced (leaked) allocations in the Leak View.


Snapshot Views

Snapshot Views

Use these buttons to open a view on the currently selected snapshot.

  • Call Tree View
  • Memory View
  • Functions View
  • Types View
  • Leaks View

Snapshot views can also be opened by right clicking in the snapshot list view and from the main menu.


Call Tree View

Call Tree View

The Call Tree View shows where in your application memory was allocated from. Each allocation stores a callstack, these callstacks are combined into a tree of callstacks and the memory is aggregated for each symbol.

The Grouping Editor is a powerful way of breaking down this information into categories.

This is probably the most useful view in MemPro because it easily shows you where memory is going in your app.

  1. Reverse Hierarchy: Reverses the hierarchy so that the root is the allocation function. This can be useful if you want to find out the functions that allocate the most memory.
  2. Source Code: Toggle the source code view window.
  3. Grouping Editor: Show the grouping editor. See the Grouping Editor page for more details.
  4. Apply Grouping: Apply the grouping that is currently shown in the grouping dropdown box.
  5. Auto Expand: Auto expand the currently selected row and all of its child rows that contains more than the n% of the applications allocated memory. The value n is set in the box to the right of this button. You can also auto expand by right clicking on a row.
  6. Call Tree: This shows a tree of all of the callstack entries that directly or indirectly allocated memory.
  7. Count: The number of allocations that were allocated at this symbol (including sub symbols)
  8. Memory: The amount of memory allocated by this symbol (includes sub symbols)
  9. Percent: Percent of the total memory allocated by the process.
  10. Source Code Window: Shows the file and line for the currently selected symbol


Call Tree Grouping

Call Tree Grouping

Overview

The Grouping editor groups callstacks using wildcard filters.

Each symbol in a callstack is evaluated against the group wildcards to determine which group belongs to. The groups are checked in the order that they appear in the Group list. When a match is ground it stops checking the other groups. Any callstacks that don't match any groups are put into the untracked unfiltered.

A grouping is a collection of groups. You can create multiple groups and switch between them using the dropdown box at the top of the window. Groups can be saved and loaded independently of the session.

How to use

  1. Create a new grouping using the 'New' button (see point 3 in the GUI diagram)
  2. The new group will appear in the Saved Groupings list box with a default name. Double click on the name to rename it.
  3. Enter the group names and group wildcards in the Group list (point 4). You can have as many groups as you want, they will be evaluated in the order they appear here. Drag and slide to re-order.
  4. Click 'Apply Groups' to refresh the call tree with your new grouping.

1. Grouping Editor Toggle Button: | show/hide the grouping panel
2. Apply Grouping: | Refresh the call tree with the current grouping that is shown in the grouping dropdown box.
3. New Grouping: | Create, load and save groupings. Once a grouping is created it will show in the Saved Groupings list box.
4. Group List: | List of all rule names in the current grouping
5. Group Wildcards: | Wildcards for the groups in the current grouping.


Memory View

Memory View

The Memory View shows:

  • The entire virtual address space
  • The state of all 4K pages
  • All Allocations
  • The contents of memory

In the top right of the window are check boxes where you can enable and disable viewing of specific types of memory. These boxes also serve as a colour key for the different memory states.

The memory bars show the memory state at 3 different zoom levels. Click on a bar to show that memory in the next bar down. Right click and drag to scroll, and use the mouse wheel to zoom.

You can use the Memory View to:

  • View memory fragmentation
  • Determine cache locality
  • View the contents of memory

GUI:

  1. Virtual Memory Bar: This bar shows memory at the most zoomed out level. There are multiple 4K pages per pixel. Each page range is indicated with a small black line above the bar. The red zig-zag lines indicate that MemPro is not showing all of the free pages to save space (hover your mouse over and see the memory location jump).

    Left Click on the bar to show that memory in the 4K Page Memory Bar.
    Right mouse button to drag and scroll.
    Mouse wheel to zoom
  2. 4K Page Memory Bar: This bar shows memory at the 4K page level. Pages are divided by black lines. The bar is scrolled to the currently selected The selected page will be shown by black rectangles above and below the page.

    Left Click on the bar to show that memory in the Allocation Memory Bar.
    Right mouse button to drag and scroll.
    Mouse wheel to zoom
  3. Allocation Page Memory Bar: This bar shows the memory allocations, down to byte resolution. The bar is scrolled to the currently selected 4K page in the page bar.
    Left Click on an allocation to view more details below.
    Right mouse button to drag and scroll.
    Mouse wheel to zoom
  4. Page Stats: Shows information on the currently selected 4K page.
    Address | Start address of the page
    State | Free, Reserved or Committed
    Type | Image, Mapped, Private
  5. Allocation: Shows information on the currently selected allocation.
    State | Allocated or Free
    Address | Address of the start of the allocation
    Size | Size of the allocation

  6. Callstack: Shows the callstack of the currently selected allocation.
  7. Memory Contents: Shows the contents of the memory for the currently selected allocation.
    You can type an address in the address text box to go to any address. The dropdown on the right controls how many columns are visible. Right click on the memory contents to bring up a context menu where you can specify how the memory bytes should be displayed.

    Note: this is only available if you have taken a Full Callstack. See the Full Callstack page for more info.
  8. Current Memory Address: Shows the memory address at the mouse cursor when the mouse is over one of the memory bars.


Functions View

Functions View

Overview

The Functions View shows a breakdown of memory by function.

Inclusive means the memory that is allocated by that function or the functions it calls.

Exclusive means the memory that is allocated only by that function.

The % columns are the memory as a percentage of the total allocated memory


Types View

Types View

Overview

The Types View shows the allocations broken down by type, with type being the type of object that is being allocated.

How does it work?

For each line in the callstack MemPro will try and find the file and line of the source code. If that looks like a call to new it will work out the type of data being allocated. For example, this might be the callstack:

`anonymous namespace'::TestInfiniteAllocs (+232) - mempro_test.cpp(443)
wmain (+98) - mempro_test.cpp(580)
__tmainCRTStartup (+447) - crtexe.c(552)
wmainCRTStartup (+15) - crtexe.c(371)
wkernel32.pdb: (0x773B33AA) (+0)

MemPro checks the line in mempro_test.cpp and finds:
char* p = new char[size];

It can then work out that the type of object being allocated is a char.

Why is it only showing 'untracked'

There are a couple of reasons that MemPro can't work out the type. One is that the application is not using new/delete but its own allocation functions. The other is that MemPro can't find the source code files. This can happen if the application as compiled on another machine for example.


Leak View

Leak View

Overview:

MemPro tracks leaks in three ways:

  • Allocations that are not freed on exit.
  • Allocations that are not referenced by anything else in the process.
  • Allocation callstacks that have specific memory allocation patterns

Unreferenced Allocations

Unreferenced allocations are:

  • Any allocations that have not been freed when the app are exited
  • Any allocations that are not referenced by anything else in memory
    (note: To use this feature you must take a full snapshot).

The latter type of unreferenced allocations can be detected while the application is still running. MemPro will take a snapshot of the entire process memory and scan it for pointers to allocations. Any allocations that MemPro can't find a pointer to are considered as leaked.

Suspected Leaks

MemPro analyses the allocation patterns of all callstacks. Allocations are grouped by the callstack. Simply put, if a callstack is constantly allocating memory and never freeing it then the callstack graph will look like a diagonal line (bottom left to top right). MemPro uses a set of heuristics to analyse the callstack graph to see how much it looks like a leak and then gives that callstack a score from 0 to 100, 100 being a definite leak. Callstack graphs are normalised, so only the shape of the graph should be taken into consideration.

MemPro will probably bring up some false positives, to eliminate these you can use the exclusion filters discussed below and the minimum leak score.

By default MemPro will only list the first 500 allocations. This is to keep the GUI responsive. This limit can be changed in the settings.

Leak View:

1. Callstacks with Leaks | The number of callstacks with definite leaks. Definite leaks are allocations that have not been cleaned up on exit or that are not referenced by anything else in memory.
2. Leaked Allocations | The number of leaked allocations
3. Leaked Memory | The amount of leaked memory
4. Suspect callstacks | The number of callstacks that look like they are leaking. These are evaluated using the leak heuristics.
5. Suspected Memory Leaked | Amount of leaked memory from suspected leaks.
6. Minimum Certainty | Suspected leaks need to have a confidence percent greater than this value to be considered a leak.
7. Summary | Here MemPro will tell you how many definite leaks you have, and how many suspected leaks you have.
8. Exclude Filter | MemPro will almost certainly show some false positives in the suspect leaks. You can exclude these using this exclude filter list. Enter wildcards, any callstack that has a symbol that matches one of these wildcards will be excluded.
9. Scoring Heuristics | Here you can control what heuristics MemPro uses to evaluate the callstacks for suspected leaks. It is recommended that you leave these enabled unless you fully understand how they work, otherwise you may get a lot of false positives. Deceleration: How much the gradient slows down in the last third of the time scale (Callstacks that slow down in the memory allocations are usually not leaks). Age distribution: How many allocations there are and how evenly spaced they are. Lots of regular allocations are more likely to be leaks. Amount Leaked: Difference from the start and end of the timescale. If a callstack frees as much as it allocates it is not leaking.
10. Callstack of Expanded Leak | All of the callstacks that MemPro thinks are leaking will be listed here. Click on the rows to expand or collapse them. The are ordered by the amount leaked for definite leaks, and then by the confidence value of suspect leaks.
11. Information about Leak | Leaked Memory: How much memory is definitely leaked (unreferenced allocations) Leaked Allocations: How many allocations are leaked (unreferenced) Suspect Leak Confidence: How confident MemPro is that this callstack is leaking. Suspect Leaked Memory: The amount of suspected leaked memory Suspect Leaked Allocations: The number of suspected leaked allocations Gradient: How much the gradient is increasing in the last third of the time ramge. Deceleration: How much the callstack is decelerating in the last third of the time range. Age Distribution: How many allocations there are and how tightly packed they are.
12. Callstack Graph | The graph of the callstack. The more red it is, the more it is leaking. Leaked allocations are shown as small red squares. The graph is normalised over the time range and amount of memory leaked.


App Toolbar

App Toolbar

Subtract Snapshots | Create a snapshot by subtracting one existing snapshot from another.
Rewind Memory | Rewind memory to see what was previously allocated at a specific address
VMem View | Open the VMem view. VMem is a general purpose memory allocator also written by Stewart Lynch. When VMem is used in the application it will send data to MemPro. MemPro will display data on all of the allocators.


Subtract Snapshots

Subtract Snapshots

Overview:

Subtracting one snapshot from another snapshot is a useful way to find memory leaks and memory spikes. It can show you everything that was allocated and freed in a time range.

How to Use:

  1. Take two snapshots and then click on the 'Subtract Snapshots' button (or from the tools menu).
  2. You will then see a dialog where you can select the two snapshots that you are interested in.
  3. This will create a new snapshot which will be displayed in the snapshot list view.
  4. You can then view this snapshot just like any other snapshot.
  5. Note that the snapshot may contain negative values if some call sites have freed more than they have allocated.

Subtracting using the graph view

There is a quick way to achieve the above using the graph view. Right click at the start of the range you are interested in and drag the mouse to the end of the range. You will see a blue transparent rectangle.

MemPro will automatically take a snapshot at the start and end of this range, and create a new snapshot that is a subtraction of the two snapshots.

These new snapshots will appear in the snapshot list view and you can view them in the normal way.


Rewind Memory

Rewind Memory

Overview

This view lets you rewind and fast-forward time to see all allocation and free events that happened in a specific range of memory.

Once you specify a range of memory, MemPro will go back through the allocation history file and find all allocations and frees that overlap with this range. It stores these allocations and frees as events. you can then scrub backwards and forwards through these events to see what was allocated and when.

What is this view useful for?

This view is very useful for tracking down memory corruptions. Most corruptions happen because something is writing to memory that it doesn't own anymore. Its memory has been freed and is probably being used by something else. When it writes to that memory it causes undefined behaviour or a crash. Because the crash happens when that memory is used again it can be very difficult to work out what actually wrote to that memory. This view solves that problem, you can rewind memory and see what was previously allocated at the corruption address.

1. Min/Max Address | Enter the minimum and maximum addresses of the range of memory that you are interested in.
2. Get History | Once you have entered min/max addresses, hit 'Get History' to get the history of all allocations and frees within that range.
3. Prev/Next Event | Use these buttons to move to the next and previous event. The time slider bar and the Events list view will show the current event.
4. Event time slider | Allocation events are shown as green lines. Free events are shown as red lines. Drag the slider to move between events. The black triangle shows the current event.
5. Allocations bar | Similar to the memory bars in the Memory View. Shows the allocations in the current range. Click on an allocation (green rect) to get more information about that alloction. Drag the time slider across events and see the allocations appear and disappear and they are allocated and freed.
6. Event List | Shows all of the allocation and free events in the memory range. The address is the address of the allocation that is being allocated or freed, similarly for the size and the time. Selecting these events will also update the time slider.
7. Allocation Information | Shows information about the currently selected allocation in the allocation memory bar. Shows the allocation start and end addresses, the size of the allocation and the allocation callstack.


VMem View

VMem View

Open this view while connected to an application that is compiled with VMem. VMem is a general purpose malloc replacement also written by Stewart Lynch. To make VMem talk to MemPro define MEMPRO before including VMem.cpp.

This view shows information on all of the heaps and allocators in VMem. For more information on this please refer to the VMem technical documentation.


Settings Toolbar

Settings Toolbar

MB (units) | Changes the units that all of the displayed memory values in MemPro. Cycles through GB, MB, K, Bytes
Symbol Paths | Shows the symbol paths dialog
Settings | Shows the settings dialog


Symbol Paths Dialog

Symbol Paths Dialog

Enter paths that MemPro will use when looking for symbol pdb files.

Note: Do not enter paths of pdb files, only enter directories.


Settings

Settings

History Path | While MemPro is connected and collecting allocations it stores all allocations in a file in disk. As you can imagine, this file can get quite big. Please ensure that you have plenty of disk space available. You can change the path that MemPro will save the history file here. MemPro will reuse the same history file for each session. When you save a mempro file you have the option of embedding the history file.
Units | Changes the units that the GUI used. Can be GB, MB, K or bytes. Most places that show a memory value will use these units. You can also changes the units using the units button on the GUI.
Embed Allocs file in save files | The allocs file is another name for the history file. If this is checked MemPro will embed the allocs file in the mempro save files. If the allocs file is huge then MemPro will warn you to verify that you really do want to embed it.
Embed pdb file in save files | MemPro can embed pdb files into mempro save files. This is useful because it means that you don't have to keep the pdb files for each mempro file. If this is checked MemPro will embed the pdb files by default. Pdb files can take up a lot of memory, so if they are above a certain size, MemPro will still warn you and let you choose not to embed them.
Check for updates | If this is checked MemPro will check with the PureDev Software servers to see if a newer version of MemPro is available for download. If it is you will be prompted to download and installed the new version.

Launch Exe, args and working directory These settings mirror the Launch Dialog settings. The settings are saved so that you don't have to enter them each time you run MemPro.

Connect IP and Port These settings mirror the Connect Dialog settings, with the addition of the secondary port. If MemPro can't connect on the default port (27016), it will try the secondary port. This can be useful when debugging on more than one machine. The settings are saved so that you don't have to enter them each time you run MemPro.

Callstack Filters Symbols in callstacks that match these wildcards are removed and not shown in the Call Tree view. Useful for removing the MemPro tracking functions and new/delete calls. * are automatically added to the start and end of each entry.


MemPro Unix/GCC

MemPro on Unix/gcc

While the MemPro app only runs on Windows, it can profile an application on virtually any platform or OS. This can be done either by connecting to the app over the network or in offline mode.

On Windows MemPro automatically finds and reads the pdb symbol files. When using gcc it's a bit more complicated. Symbol txt files need to be generated by hand. Use the steps below to generate them.

  1. Compile your application with -g to embed the debug symbols in the exe

  2. Use rm to dump out the symbols to a text file. Open up a terminal and type the following, replacing exe_path and exe_name:

    nm -g --line-numbers --demangle exe_path >exe_name.sym_txt

  3. Copy the sym_txt file to your PC and add its path to the MemPro Symbol Paths

Notes:

In step 2 the exe_path includes the exe filename, for example
/home/slynch/Documents/code/MemPro_Test/MemPro_Test/bin/Debug/MemPro_Test
Where MemPro_Test is the name of the executable.

The name of the sym_txt file must match the executable name exactly (apart from the extension of course). In the example above the executable name is MemPro_Test

Putting it all together:
nm -g --line-numbers --demangle /home/slynch/Documents/code/MemPro_Test/MemPro_Test/bin/Debug/MemPro_Test >MemPro_Test.sym_txt
This will create a file MemPro_Text.sym_txt. Copy that file to your PC somewhere that MemPro can find it and you will have symbols.

If you don't want to embed the symbols in your exe (they can get quite big) you can use the split command to split off the symbols into a separate file. You would then run the rm command on this file instead of the exe.

This is an example of what the sym_txt file should look like:

0804bd92 W MemPro::RingBuffer::Range::Range(void*, int) /home/slynch/Documents/code/MemProCpp/MemPro.cpp:799
0804bd8c W MemPro::RingBuffer::Range::Range() /home/slynch/Documents/code/MemProCpp/MemPro.cpp:798
0804bd92 W MemPro::RingBuffer::Range::Range(void*, int) /home/slynch/Documents/code/MemProCpp/MemPro.cpp:799

Each symbol is on a separate line. The first columns is the address (8 chars). The second column is the type (1 char). The third column is the undecorated symbol name. The last column is the file and line number. The first three columns are separated by spaces. The last column is separated by a tab char. See the rm documentation for more details.

Limitations:

The following features will not work when profiling gcc apps:

  • Virtual Memory view
  • Full Snapshots


App Toolbar

FAQ

  • Can I profile apps on Unix/gcc based systems using MemPro?

  • Compile errors in ws2def.h

  • When I try and view a snapshot MemPro is complaining about the DIA dll, what should I do?

  • No symbols have loaded, all I get is addresses in the callstack view, how do I fix this?

  • My App crashes during global initialisation when linked to MemProLib

  • Does MemPro work with 64Bit apps?

  • Which version should I use, x86 or x64?

  • How do I get MemPro to link with an MFC app?

  • Is there a way to use MemPro to profile my app without connecting using winsock?

  • Why isn't MemPro tracking all of my allocations in my MFC app?

  • Compile error: 'RtlCaptureStackBackTrace': identifier not found

  • StackWalk64 compile error

  • Calling Initialise(true) to make MemPro wait for a connection isn't working

  • Can MemPro profile applications with multiple dlls?

  • MemPro is incorrectly saying that I am leaking global objects

  • Compile error C2664: 'OutputDebugStringW' : cannot convert parameter 1 from 'const char [59]' to 'LPCWSTR'

Can I profile apps on Unix/gcc based systems using MemPro?

Answer: Yes. The MemPro app will only run on Windows, but you can connect over the network to an app on pretty much any platform. You can also use MemProLib in offline more if you don't have a network connection. See the User Guide for more information.

Compile errors in ws2def.h

c:\program files\microsoft sdks\windows\v7.0\include\ws2def.h(91) : warning C4005: 'AF_IPX' : macro redefinition
c:\program files\microsoft sdks\windows\v7.0\include\ws2def.h(212) : error C2011: 'sockaddr' : 'struct' type redefinition

Answer:This happens because MemPro includes winsock2.h which needs to be included before windows.h. If you are including windows.h before including MemPro please add an include to winsock2

#include <winsock2.h>
#include <windows.h>

...
#include "MemPro.cpp" After you have changed this do a full re-compile.
See here for more details on why winsock2.h needs to be included before windows.h

Alternatively, you can define WIN32_LEAN_AND_MEAN before including your windows.h. This strips out the winsock headers and avoids the problem.

When I try and view a snapshot MemPro is complaining about the DIA dll, what should I do?

Answer: Please see this page

No symbols have loaded, all I get is addresses in the callstack view, how do I fix this?

Answer: The first thing to do is to check the output window (View menu -> Show Output Window). The pdb may have failed to load because it couldn't be found or because its signature didn't match the executable. MemPro will only load pdb files if they exactly match the signature of the executable. MemPro will automatically detect where the pdb file was compiled to and try and load it from there. If the pdb file is not there (it was compiled on another machine for example) you can add the path of the pdb file to the symbols search paths (Settings menu -> Symbols...).

My App crashes during global initialisation when linked to MemProLib

Answer: This is probably due to the initialisation of windows sockets. In MemPro.hpp increase the MEMPRO_INIT_DELAY. MemPro will wait this number of ms before initialising the winsock. All allocations will be stored in a temporary buffer until winsock has been initialised. Failing that you can use MemPro in offline mode by defining WRITE_DUMP. MemPro will write out to a file instead of sending data over TCP. This file can then be loaded up in MemPro.

Does MemPro work with 64Bit apps?

Answer: Yes. Both the x86 and x64 versions of MemPro can now profile 64bit apps...

Which version should I use, x86 or x64?

Answer: Both the versions can profile x86 or x64 bit apps, they are entirely equivalent. You can even load up mempro files saved from one version into the other. If you have a 64bit OS I recommend the 64bit version simply because large profiles can sometimes take up more than 3Gb of memory.

How do I get MemPro to link with an MFC app?

If you're getting link errors telling you that new and delete are already defined:

1>MCFTest_2010.obj : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in mfc100ud.lib(mfc100ud.dll)
1>MCFTest_2010.obj : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in mfc100ud.lib(mfc100ud.dll)
1>MCFTest_2010.obj : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) already defined in msvcrtd.lib(MSVCR100D.dll)

Solution: Do a clean re-build of your entire project.

If you are still getting problems, make sure you are linking statically to MFC.

Is there a way to use MemPro to profile my app without connecting using winsock?

Answer:Yes. Define WRITE_DUMP in MemPro.hpp and MemPro will write out to a file instead of sending the data over sockets. This file can then be loaded up in MemPro.

Why isn't MemPro tracking all of my allocations in my MFC app?

Solution: make sure that new isn't being re-defined to the debug version. Remove the following lines from anywhere in your code

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

Compile error: 'RtlCaptureStackBackTrace': identifier not found

Answer: If you are on Win2K this function doesn't exist. Try uncommenting this line of code
//#define USE_STACKWALK64 // much slower but possibly more reliable.

Alternatively, it might be something to do with your compile settings. Please try compiling the SimpleTest sample that is installed with MemPro. If that compiles please check the compile settings for your project.

StackWalk64 compile error

Answer:Try uncommenting this line of code
//#define USE_RTLVIRTUALUNWIND

Alternatively, it might be something to do with your compile settings. Please try compiling the SimpleTest sample that is installed with MemPro. If that compiles please check the compile settings for your project.

Calling Initialise(true) to make MemPro wait for a connection isn't working

Answer: MemPro calls Initialise(WAIT_FOR_CONNECT) from TrackAlloc. This is needed because allocations can happen before main is entered (from global objects etc). It maybe that an allocation has happened before your call to Initialise(true) and Initialise(false) has already been called. to get around this problem, instead of calling Initialise(true) yourself, define WAIT_FOR_CONNECT to true in MemProLib.

Can MemPro profile applications with multiple dlls?

Answer: Yes. You will need to link to the MemProDll.dll and include MemProDll.hpp once in each of the dlls that you want to track. These files can be found in the MemPro code install folder. Please see the help setup in the README.txt or the help chm.

MemPro is incorrectly saying that I am leaking global objects

Answer: The order of global object destruction in C++ is undefined, There are cases where MemPro can shutdown before other global objects have freed their memory. Consider explicitly cleaning up your global objects as this is generally considered good practice. If that is not an option include MemPro.hpp in your main application cpp file and/or the files with global objects that are not being detected. MemPro uses a trick to attempt to shutdown after everything else, (see MemProGLobalScope), but it needs to be included before any other global objects are initialised. Failing that you can use MemPro in off-line mode which should catch all frees during global shutdown because it doesn't rely on sockets.

Compile error C2664: 'OutputDebugStringW' : cannot convert parameter 1 from 'const char [59]' to 'LPCWSTR'

Answer: for unicode builds, windows.h uses a different define from tchar.h. windows.h uses UNICODE and tchar.h uses _UNICODE. You must ensure that both UNICODE and _UNICODE are defined before including windows.h and tchar.h respectively. The mismatch occurs because OutputDebugString from windows.h is using the unicode version, and the string literals are wrapped in _T() from tchar.h that is not unicode.