{"id":13598744,"url":"https://github.com/KDE/heaptrack","last_synced_at":"2025-04-10T09:32:11.186Z","repository":{"id":1777451,"uuid":"42728217","full_name":"KDE/heaptrack","owner":"KDE","description":"A heap memory profiler for Linux","archived":false,"fork":false,"pushed_at":"2024-10-15T13:50:44.000Z","size":12960,"stargazers_count":3313,"open_issues_count":4,"forks_count":201,"subscribers_count":51,"default_branch":"master","last_synced_at":"2024-10-29T15:02:36.998Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://invent.kde.org/sdk/heaptrack","language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KDE.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSES/Apache-2.0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-09-18T14:46:29.000Z","updated_at":"2024-10-28T07:28:24.000Z","dependencies_parsed_at":"2024-02-27T03:26:43.938Z","dependency_job_id":"bd05f36a-7069-4d2b-a31c-fe4b32aa19fe","html_url":"https://github.com/KDE/heaptrack","commit_stats":{"total_commits":1459,"total_committers":83,"mean_commits":17.57831325301205,"dds":"0.43728581220013707","last_synced_commit":"5ede0d7e2f6c6d1f07b7dd442e9d513d3d12238e"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KDE%2Fheaptrack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KDE%2Fheaptrack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KDE%2Fheaptrack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KDE%2Fheaptrack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KDE","download_url":"https://codeload.github.com/KDE/heaptrack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248191779,"owners_count":21062570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T17:00:55.715Z","updated_at":"2025-04-10T09:32:06.173Z","avatar_url":"https://github.com/KDE.png","language":"C++","readme":"# heaptrack - a heap memory profiler for Linux\n\n![heaptrack_gui summary page](screenshots/gui_summary.png?raw=true \"heaptrack_gui summary page\")\n\nHeaptrack traces all memory allocations and annotates these events with stack traces.\nDedicated analysis tools then allow you to interpret the heap memory profile to:\n\n- find hotspots that need to be optimized to reduce the **memory footprint** of your application\n- find **memory leaks**, i.e. locations that allocate memory which is never deallocated\n- find **allocation hotspots**, i.e. code locations that trigger a lot of memory allocation calls\n- find **temporary allocations**, which are allocations that are directly followed by their deallocation\n\n## Using heaptrack\n\nThe recommended way is to launch your application and start tracing from the beginning:\n\n    heaptrack \u003cyour application and its parameters\u003e\n\n    heaptrack output will be written to \"/tmp/heaptrack.APP.PID.gz\"\n    starting application, this might take some time...\n\n    ...\n\n    heaptrack stats:\n        allocations:            65\n        leaked allocations:     60\n        temporary allocations:  1\n\n    Heaptrack finished! Now run the following to investigate the data:\n\n        heaptrack --analyze \"/tmp/heaptrack.APP.PID.gz\"\n\nAlternatively, you can attach to an already running process:\n\n    heaptrack --pid $(pidof \u003cyour application\u003e)\n\n    heaptrack output will be written to \"/tmp/heaptrack.APP.PID.gz\"\n    injecting heaptrack into application via GDB, this might take some time...\n    injection finished\n\n    ...\n\n    Heaptrack finished! Now run the following to investigate the data:\n\n        heaptrack --analyze \"/tmp/heaptrack.APP.PID.gz\"\n\n### Profiling on embedded machines\n\nWhen you are trying to profile a system where you do not have direct access to debug symbols, which is commonly the case\non embedded systems, the above steps won't give you useful data. There, you instead first need to record a raw trace\nfile and then later interpret it on a system where you have access to an SDK or sysroot with the required debug symbols.\n\nRecord a raw trace file on the embedded system:\n\n    heaptrack --raw \u003cyour application and its parameters\u003e\n\nThen download the raw trace file to your development machine and interpret the data:\n\n    heaptrack --interpret \"/path/heaptrack.test_c.8911.raw.zst\" --sysroot \"/path/to/sysroot\"\n\nThen, you can analyze it:\n\n    heaptrack --analyze \"/tmp/heaptrack.test_c.8911.zst\"\n\nIf you have other folders outside of the sysroot that contain debug information, you can pass them via `--debug-paths`\nto `heaptrack --interpret`, see also: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Separate-Debug-Files.html\n\nFurthermore, if you have custom code side loaded and want to load the debug information from the respective build\nfolders, use `--extra-paths`, e.g.:\n\n    heaptrack --interpret \"/path/heaptrack.test_c.8911.raw.zst\" --sysroot \"/path/to/sysroot\"\n\n## Building heaptrack\n\nHeaptrack is split into two parts: The data collector, i.e. `heaptrack` itself, and the\nanalyzer GUI called `heaptrack_gui`. The following summarizes the dependencies for these\ntwo parts as they can be build independently. You will find corresponding development\npackages on all major distributions for these dependencies.\n\nOn an embedded device or older Linux distribution, you will only want to build `heaptrack`.\nThe data can then be analyzed on a different machine with a more modern Linux distribution\nthat has access to the required GUI dependencies.\n\nIf you need help with building, deploying or using heaptrack, you can contact KDAB for\ncommercial support: https://www.kdab.com/software-services/workshops/profiling-workshops/\n\n### Shared dependencies\n\nBoth parts require the following tools and libraries:\n\n- cmake 2.8.9 or higher\n- a C\\+\\+11 enabled compiler like g\\+\\+ or clang\\+\\+\n- zlib\n- optionally: zstd for faster (de)compression\n- elfutils\n- libdl\n- pthread\n- libc\n\n### `heaptrack` dependencies\n\nThe heaptrack data collector and the simplistic `heaptrack_print` analyzer depend on the\nfollowing libraries:\n\n- boost 1.41 or higher: iostreams, program_options\n- libunwind\n\nFor runtime-attaching, you will need `gdb` installed.\n\n### `heaptrack_gui` dependencies\n\nThe graphical user interface to interpret and analyze the data collected by heaptrack\ndepends on Qt 5 and some KDE libraries:\n\n- extra-cmake-modules\n- Qt 5.2 or higher: Core, Widgets\n- KDE Frameworks 5: CoreAddons, I18n, ItemModels, ThreadWeaver, ConfigWidgets, KIO, IconThemes\n\nWhen any of these dependencies is missing, `heaptrack_gui` will not be build.\nOptionally, install the following dependencies to get additional features in\nthe GUI:\n\n- KDiagram: KChart (for chart visualizations)\n\n### Compiling\n\nRun the following commands to compile heaptrack. Do pay attention to the output\nof the CMake command, as it will tell you about missing dependencies!\n\n    cd heaptrack # i.e. the source folder\n    mkdir build\n    cd build\n    cmake -DCMAKE_BUILD_TYPE=Release .. # look for messages about missing dependencies!\n    make -j$(nproc)\n\n#### Compile `heaptrack_gui` on macOS using homebrew\n\n`heaptrack_print` and `heaptrack_gui` can be built on platforms other than Linux, using the dependencies mentioned above.\nOn macOS the dependencies can be installed easily using [homebrew](http://brew.sh) and the [KDE homebrew tap](https://github.com/KDE-mac/homebrew-kde).\n\n    brew install qt@5\n\n    # prepare tap\n    brew tap kde-mac/kde https://invent.kde.org/packaging/homebrew-kde.git\n    \"$(brew --repo kde-mac/kde)/tools/do-caveats.sh\"\n    \n    # install dependencies\n    brew install kde-mac/kde/kf5-kcoreaddons kde-mac/kde/kf5-kitemmodels kde-mac/kde/kf5-kconfigwidgets \\\n                 kde-mac/kde/kf5-kio kde-mac/kde/kdiagram \\\n                 extra-cmake-modules ki18n threadweaver \\\n                 boost zstd gettext\n    \n    # run manual steps as printed by brew\n    ln -sfv \"$(brew --prefix)/share/kf5\" \"$HOME/Library/Application Support\"\n    ln -sfv \"$(brew --prefix)/share/knotifications5\" \"$HOME/Library/Application Support\"\n    ln -sfv \"$(brew --prefix)/share/kservices5\" \"$HOME/Library/Application Support\"\n    ln -sfv \"$(brew --prefix)/share/kservicetypes5\" \"$HOME/Library/Application Support\"\n\nTo compile make sure to use Qt from homebrew and to have gettext in the path:\n\n    cd heaptrack # i.e. the source folder\n    mkdir build\n    cd build\n    CMAKE_PREFIX_PATH=/opt/homebrew/opt/qt@5 PATH=$PATH:/opt/homebrew/opt/gettext/bin cmake ..\n    cmake -DCMAKE_BUILD_TYPE=Release .. # look for messages about missing dependencies!\n    make heaptrack_gui heaptrack_print\n\n## Interpreting the heap profile\n\nHeaptrack generates data files that are impossible to analyze for a human. Instead, you need\nto use either `heaptrack_print` or `heaptrack_gui` to interpret the results.\n\n### heaptrack_gui\n\n![heaptrack_gui flamegraph page](screenshots/gui_flamegraph.png?raw=true \"heaptrack_gui flamegraph page\")\n\n![heaptrack_gui allocations chart page](screenshots/gui_allocations_chart.png?raw=true \"heaptrack_gui allocations chart page\")\n\nThe highly recommended way to analyze a heap profile is by using the `heaptrack_gui` tool.\nIt depends on Qt 5 and KF 5 to graphically visualize the recorded data. It features:\n\n- a summary page of the data\n- bottom-up and top-down tree views of the code locations that allocated memory with\n  their aggregated cost and stack traces\n- flame graph visualization\n- graphs of allocation costs over time\n\n### heaptrack_print\n\nThe `heaptrack_print` tool is a command line application with minimal dependencies. It takes\nthe heap profile, analyzes it, and prints the results in ASCII format to the command line.\n\nIn its most simple form, you can use it like this:\n\n    heaptrack_print heaptrack.APP.PID.gz | less\n\nBy default, the report will contain three sections:\n\n    MOST CALLS TO ALLOCATION FUNCTIONS\n    PEAK MEMORY CONSUMERS\n    MOST TEMPORARY ALLOCATIONS\n\nEach section then lists the top ten hotspots, i.e. code locations that triggered e.g.\nthe most memory allocations.\n\nHave a look at `heaptrack_print --help` for changing the output format and other options.\n\nNote that you can use this tool to convert a heaptrack data file to the Massif data format.\nYou can generate a collapsed stack report for consumption by `flamegraph.pl`.\n\n## Comparison to Valgrind's massif\n\nThe idea to build heaptrack was born out of the pain in working with Valgrind's massif.\nValgrind comes with a huge overhead in both memory and time, which sometimes prevent you\nfrom running it on larger real-world applications. Most of what Valgrind does is not\nneeded for a simple heap profiler.\n\n### Advantages of heaptrack over massif\n\n- *speed and memory overhead*\n\n  Multi-threaded applications are not serialized when you trace them with heaptrack and\n  even for single-threaded applications the overhead in both time and memory is significantly\n  lower. Most notably, you only pay a price when you allocate memory -- time-intensive CPU\n  calculations are not slowed down at all, contrary to what happens in Valgrind.\n\n- *more data*\n\n  Valgrind's massif aggregates data before writing the report. This step loses a lot of\n  useful information. Most notably, you are not longer able to find out how often memory\n  was allocated, or where temporary allocations are triggered. Heaptrack does not aggregate the\n  data until you interpret it, which allows for more useful insights into your allocation patterns.\n\n### Advantages of massif over heaptrack\n\n- *ability to profile page allocations as heap*\n\n  This allows you to heap-profile applications that use pool allocators that circumvent\n  malloc \u0026 friends. Heaptrack can in principle also profile such applications, but it\n  requires code changes to annotate the memory pool implementation.\n\n- *ability to profile stack allocations*\n\n  This is inherently impossible to implement efficiently in heaptrack as far as I know.\n\n## Heaptrack with Rust\n\nIn general, Heaptrack mostly works with Rust binaries out of the box, as Rust programs include the corresponding debug symbols.\nDemangling is not yet supported, however most symbol names are still decipherable.\n\nThere are also a few other details to keep in mind.\n\n### Enable debug symbols\nIf building in release mode, make sure [debug symbols](https://doc.rust-lang.org/cargo/reference/profiles.html#debug) are enabled.\n\nAdd this to your Cargo.toml:\n```\n[profile.release]\ndebug = true\n```\n⚠️ Note that if your project is part of a Workspace, this must be added to the Workspace Cargo.toml, not to the individual crate.\n\n### Running Heaptrack on a Rust binary\n\nRunning `heaptrack cargo run` will not work as intended, as this will profile Cargo's memory usage, not that of your application.\n\nInstead either:\n1. Compile your binary as normal with `cargo build --release` and run heaptrack on the resulting binary in the `target/release/` directory.\n    * e.g.: `heaptrack ./target/release/my-rust-app`\n2. Install [cargo-heaptrack](https://crates.io/crates/cargo-heaptrack) (unofficial) and run `cargo heaptrack`.\n    * ⚠️ Make sure to run the analysis command as prompted by the command-line output before opening the GUI\n\n### Opening Rust source files via Heaptrack\n\nIn Heaptracks GUI under the Callee/Caller graph, you can double-click a location to open an editor there.\n\nThe file paths are relative, so make sure to open the heaptrack GUI at the root of your project, in order for this to work correctly.\n\n⚠️ If your crate is part of a workspace, you need to open heaptrack at the root of the workspace for the paths to be correct.\n\n## Contributing to heaptrack\n\nAs a FOSS project, we welcome contributions of any form. You can help improve the project by:\n\n- submitting bug reports at https://bugs.kde.org/enter_bug.cgi?product=Heaptrack\n- contributing patches via https://invent.kde.org/sdk/heaptrack\n- translating the GUI with the help of https://l10n.kde.org/\n- writing documentation on https://userbase.kde.org/Heaptrack\n\nWhen submitting bug reports, you can anonymize your data with the `tools/anonymize` script:\n\n    tools/anonymize heaptrack.APP.PID.gz heaptrack.bug_report_data.gz\n\n## Known bugs and limitations\n\n### Issues with old gold linker\n\nLibunwind may produce bogus backtraces when unwinding from code linked with old versions of the gold linker.\nIn such cases, recording with heaptrack seems to work and produces data files. But parsing these data files\nwith heaptrack_gui will often lead to out-of-memory crashes. Looking at the data with heaptrack_print, one\nwill see garbage backtraces that are completely broken.\n\nIf you encounter such issues, try to relink your application and also libunwind with `ld.bfd` instead of `ld.gold`.\nYou can see if you are affected by running the libunwind unit tests via `make check`. But do note that you\nneed to relink your application too, not only libunwind.\n\n### Executables built with ASAN (Address Sanitizer)\n\nIf you run heaptrack on an application built with ASAN, you'll likely get this fatal error on startup:\n\n    ASan runtime does not come first in initial library list [...]\n\nThe solution is to pass the `--asan` flag to heaptrack.\nNote: this only work for binaries built with `gcc` (i.e. those which link to `libasan.so`).\nBinaries built with `clang`'s ASAN enabled are not supported at the moment.\n\n","funding_links":[],"categories":["Debug","C++","Development Environment","Memory","Tools","General utilites"],"sub_categories":["Debugging and Tracing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKDE%2Fheaptrack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKDE%2Fheaptrack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKDE%2Fheaptrack/lists"}