Skip to content

d99kris/heapusage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

89 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Heapusage

Linux Mac
Linux macOS

Heapusage is a light-weight tool for finding heap memory errors in Linux and macOS applications. It provides a small subset of Valgrind's memcheck functionality, and can be a useful alternative to it for debugging memory leaks in certain scenarios such as:

  • Large complex applications which cannot be run at Valgrind slowdown speed
  • Embedded systems with CPU architectures not supported by Valgrind

Like Valgrind, it is recommended to run Heapusage on a debug build of the application to be analyzed.

While Heapusage has less performance impact than Valgrind, its analysis is less precise. It may report leaks originating from system libraries (e.g. libc functions like printf()) that might be free'd when the system library is being cleaned up.

Example Usage

$ heapusage -t leak ./ex001
Heapusage - https://github.com/d99kris/heapusage
Command: ./ex001
Process: 34634

HEAP SUMMARY:
    in use at exit: 12221 bytes in 4 blocks
  total heap usage: 5 allocs, 1 frees, 13332 bytes allocated
   peak heap usage: 13332 bytes allocated

6666 bytes in 3 block(s) are lost, originally allocated at:
   at 0x00000001006e18b8: malloc_wrap + 192
   at 0x00000001006bc850: main + 96
   at 0x000000019ac3eb98: start + 6076

5555 bytes in 1 block(s) are lost, originally allocated at:
   at 0x00000001006e18b8: malloc_wrap + 192
   at 0x00000001006bc808: main + 24
   at 0x000000019ac3eb98: start + 6076

LEAK SUMMARY:
   definitely lost: 12221 bytes in 4 blocks

Supported Platforms

Heapusage is primarily developed and tested on macOS, but basic functionality should work on Linux as well. Current version has been tested on:

  • macOS Sequoia 15.7
  • Ubuntu 24.04 LTS

Limitation: On macOS this tool relies on code injection using DYLD_INSERT_LIBRARIES, which generally does not work with third-party applications in a standard system. Using it on (your own) applications built from source should work fine though. See this FAQ for more details.

Installation

Pre-requisites (Ubuntu):

sudo apt install git cmake build-essential

Optional pre-requisite for source filename/line-number in callstacks (Ubuntu):

sudo apt install binutils-dev

Download the source code:

git clone https://github.com/d99kris/heapusage && cd heapusage

Build:

mkdir -p build && cd build && cmake .. && make -s

Optionally install in system:

sudo make install

Usage

General usage syntax:

heapusage [-d] [-m minsize] [-n] [-o path] [-t tools] PROG [ARGS..]
heapusage --help
heapusage --version

Options:

-d     debug mode, running program through debugger

-m <minsize>
       min alloc size to enable analysis for (default 0)

-n     no symbol lookup (faster)

-o <path>
       write output to specified file path, instead of stderr

-s <SIG>
       enable on-demand logging when signalled SIG signal

-t <tools>
       analysis tools to use (default "error")

PROG   program to run and analyze

[ARGS] optional arguments to the program

--help display this help and exit

--version
       output version information and exit

Supported tools (for option -t):

all    enables double-free, leak, overflow and use-after-free

error  enables double-free, overflow and use-after-free

double-free
       detect free'ing of buffers already free'd

leak   detect memory allocations never free'd

overflow
       detect buffer overflows, i.e. access beyond allocated memory

use-after-free
       detect access to free'd memory buffers

Examples:

heapusage ./ex001
       analyze heap for double-free, overflow, and use-after-free errors.

heapusage -t leak ./ex001
       analyze heap for memory leaks.

heapusage -t all -m 0 ./ex002
       analyze heap allocations of any size with all tools.

Output Format

Example output (with -t leak):

Heapusage - https://github.com/d99kris/heapusage

HEAP SUMMARY:
    in use at exit: 12221 bytes in 4 blocks
  total heap usage: 5 allocs, 1 frees, 13332 bytes allocated
   peak heap usage: 13332 bytes allocated

6666 bytes in 3 block(s) are lost, originally allocated at:
   at 0x00007fd04d062c88: malloc (humain.cpp:154)
   at 0x00005611e856c1a4: main (ex001.c:29)
   at 0x00007fd04ce470b3: __libc_start_main
   at 0x00005611e856c0ae: _start

5555 bytes in 1 block(s) are lost, originally allocated at:
   at 0x00007fd04d062c88: malloc (humain.cpp:154)
   at 0x00005611e856c17f: main (ex001.c:19)
   at 0x00007fd04ce470b3: __libc_start_main
   at 0x00005611e856c0ae: _start

LEAK SUMMARY:
   definitely lost: 12221 bytes in 4 blocks

Source code filename and line numbers are only supported on Linux, when package binutils-dev is available. On macOS one can use atos to determine source code details.

Advanced Usage

On-demand report can be requested by utilizing the -s flag and specifying a signal, and the sending the signal to the process. Example:

./build/heapusage -s SIGUSR1 -t all -m 0 -o hu.txt nano
kill -s SIGUSR1 $(pidof nano)

Programs can also link libheapusage and call hu_report() for an on-demand report, see tests/ex007.cpp for an example.

Note that on-demand reporting will reflect the state when they are used, and will thus report memory currently in use that might still be released before the program exits, and therefore not necessarily constitute a memory leak.

Heapusage uses a default call stack limit of 20 frames per call stack. It is possible to change this value at build time by using the HU_MAX_CALL_STACK CMake variable.

FAQ

1. What can cause error: unable to preload libheapusage on macOS?

On macOS this tool relies on code injection using DYLD_INSERT_LIBRARIES, which generally does not work with third-party applications in a standard system, unless the application is built with com.apple.security.get-task-allow entitlements (allowing debugging). Sometimes it's possible to analyze an application by modifying the app bundle and adding this entitlement by running the following command (note: this will modify the app bundle and may break it):

heapusage -c /Applications/SomeApplication.app

Technical Details

Heapusage intercepts calls to malloc/free/calloc/realloc and logs each memory allocation and free. For overflow and use-after-free it uses protected memory pages using mprotect() to detect writing outside valid allocations.

Limitations

Heapusage does currently not intercept calls to:

  • aligned_alloc
  • malloc_usable_size
  • memalign
  • posix_memalign
  • pvalloc
  • valloc

Platforms supported:

  • macOS 10.12 onwards (Mac OS X or older not supported)
  • Linux 2.6.31 onwards on CPU architectures x86 / amd64 / aarch64

Third-party Libraries

Heapusage is implemented in C++. Its source tree includes the source code of the following third-party libraries:

Alternatives

There are many heap memory debuggers available for Linux and macOS, for example:

  • Address Sanitizer / Leak Sanitizer
  • Electric Fence
  • Mtrace
  • Valgrind

License

Heapusage is distributed under the BSD 3-Clause license. See LICENSE file.

Keywords

linux, macos, heap usage, finding memory leaks, alternative to valgrind.

About

Find memory leaks in Linux and macOS applications

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors