Skip to content

toggysmith/memoryhound

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Memory Hound

Memory Hound, also known as mhound, is a tool for recording the memory usage of arbitrary processes and analysing the collected data, so that programmers can optimise their programs and detect memory-related bugs such as memory leaks. It consists of two components:

  • The tracer which is responsible for collecting memory usage data.
  • The analyser which is responsible for allowing the user to analyse the collected data.

Prerequisites

Install Clang and CMake for the tracer and Node.js and NPM for the analyser:

sudo apt update
sudo apt install clang cmake nodejs npm

Confirm that all four tools are installed:

clang -v
cmake --version
node -v
npm -v

Memory Hound has been tested with the following versions:

Ubuntu clang version 14.0.0-1ubuntu1.1
cmake version 3.22.1
node v22.14.0
npm 10.9.2

Building

There is a script offered that should automatically build the tracer and analyser, however if this does not work there are manual build instructions.

Automatic

At the root of the project, run the following command to build the tracer and analyser:

sudo ./Build.sh

Confirm that the newly created Build directory has the following files and directories:

  • mhound (tracer launcher)
  • libmhound-tracer.so (tracer attachment)
  • UnitTestRunner (unit test runner for the tracer)
  • IntegrationTestRunner (integration test runner for the tracer)
  • IntegrationTestPrograms (some programs used as part of the integration test)
  • analyser (directory containing the analyser)

Manual

If you are building manually because the automatic script failed, you may want to reset the project.

At the root of the project, create a Build directory to store build artefacts.

Building the Tracer

Navigate to the Tracer directory and run the following commands:

cmake -B build
cmake --build build

Go inside of the build directory and copy mhound, libmhound-tracer.so, UnitTestRunner, IntegrationTestPrograms, and IntegrationTestRunner to the Build directory created before.

Building the Analyser

Navigate to the Analyser directory and run the following commands:

npm install
sudo npm run make

Go inside of the out/make/zip directory and keep going down until you find a .zip.

Create an analyser directory in the Build directory.

Extract the contents of the .zip. You will get a directory structure like mhound-linux-x64-1.0.0 with another mhound-linux-x64-1.0.0 inside and then inside of that there will be all of the files for the analyser. Copy only these inner files and directories to the analyser directory. You should end up with an executable at path Build/analyser/mhound.

Testing

To run the unit tests for the tracer, run the following executable:

./Build/UnitTestRunner

To run the integration test for the tracer, run the following executable:

./Build/IntegrationTestRunner

For both of these, you can use the --help flag to get more options. For instance, -s will show successful test cases.

Usage

The target program

Create an example program such as:

#include <malloc.h>

int main() {
    void* ptr1 = malloc(4);
    void* ptr2 = malloc(6);
    free(ptr1);
    void* ptr3 = malloc(10);
    free(ptr2);
    free(ptr3);
}

and save it as main.cpp.

Build the program using Clang:

clang++ -g -O0 -no-pie -gdwarf-4 main.cpp -o app

These flags are all important:

  • -g tells Clang to build the executable with debug symbols and -gdwarf-4 tells Clang to include DWARF 4 debugging information. This debugging information is used by Memory Hound to generate readable backtraces for calls to memory management functions.
  • -O0 tells Clang not to make optimisations. This stops Clang from optimising away functions which makes the backtraces less readable.
  • -no-pie tells Clang not to build a position-independent executable. PIE is a mechanism that randomises the base address of an executable each time it is executed, which is great for security but bad for Memory Hound trying to figure out addresses in the backtrace.

Memory Hound will work without these flags but there will not be readable/useful backtraces.

ASLR (Address Space Layout Randomisation)

ASLR (Address Space Layout Randomisation) is a security technique that randomises the memory addresses where executables and libraries are loaded. Compiling the target program as -no-pie does ensure the executable's code remains at a predictable location, but other aspects of the virtual memory such as the heap will still be randomised. Disabling ASLR can make some of e.g. the pointers returned by malloc() more predictable. This is not strictly necessary though.

Disable ASLR with:

sudo sysctl -w kernel.randomize_va_space=0

ASLR is reenabled after a system reboot.

Tracing

Navigate to executable ./Build/mhound (this is the tracer) and run it on the target executable:

./mhound ./app

WARNING: Memory Hound cannot figure out executables from the PATH environment variable, so the full path to a program must be specified, e.g. ./mhound /usr/bin/ls instead of ./mhound ls.

The tracer should generate a trace/ directory and inside there should be a trace.json file. Confirm this exists before proceeding.

Analysis

Start the analyser which is also in ./Build:

./analyser/mhound

This will open a GUI window. Click on "Load a new trace" and open the trace.json file.

image

You can look at the tabs on the left side to see different information. For instance, the cumulative memory usage over time is shown below:

image

This maps to what we would expect from the example program.

About

A heap profiler for Linux

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors