{"id":21601484,"url":"https://github.com/simple-robotics/code-analysis-tools","last_synced_at":"2026-03-09T20:01:45.811Z","repository":{"id":163513876,"uuid":"570194003","full_name":"Simple-Robotics/code-analysis-tools","owner":"Simple-Robotics","description":"Guidelines and notes about useful tools to analyze and optimize code","archived":false,"fork":false,"pushed_at":"2025-11-20T09:37:12.000Z","size":665,"stargazers_count":43,"open_issues_count":0,"forks_count":9,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-11-20T11:29:28.666Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"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/Simple-Robotics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-11-24T14:53:49.000Z","updated_at":"2025-11-20T09:37:13.000Z","dependencies_parsed_at":"2024-12-17T16:21:18.245Z","dependency_job_id":"437a7a50-fa71-407e-bd42-b71876ff4ac4","html_url":"https://github.com/Simple-Robotics/code-analysis-tools","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Simple-Robotics/code-analysis-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simple-Robotics%2Fcode-analysis-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simple-Robotics%2Fcode-analysis-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simple-Robotics%2Fcode-analysis-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simple-Robotics%2Fcode-analysis-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Simple-Robotics","download_url":"https://codeload.github.com/Simple-Robotics/code-analysis-tools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simple-Robotics%2Fcode-analysis-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30309999,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T17:35:44.120Z","status":"ssl_error","status_checked_at":"2026-03-09T17:35:43.707Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-11-24T19:09:38.881Z","updated_at":"2026-03-09T20:01:45.801Z","avatar_url":"https://github.com/Simple-Robotics.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# code-analysis-tools\n\nGuidelines and notes about useful tools to analyze and optimize code.\n\nThe idea is to gather some tools that we use to develop high performance code. We should provide information about how to install and use these tools.\nLet's begin by collecting all instructions here and later move them to subfolders for each tool if readme gets confusing.\n\n## Compiling\n\nUse **cache** to speed up the compilation. If you compile the same project again and again with small changes, this can save you a lot of time. It is easy to setup. Installation via [conda](https://anaconda.org/conda-forge/ccache) or via [apt-get](https://zoomadmin.com/HowToInstall/UbuntuPackage/ccache). See the manual for the different [run modes](https://manpages.ubuntu.com/manpages/jammy/man1/ccache.1.html). For cmake, you can use a flag\n\n```\ncmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_CXX_COMPILER_LAUNCHER=ccache\n```\n\nUse [Clang](https://clang.llvm.org/) \u0026 [Ninja](https://github.com/ninja-build/ninja) to speed up the compilation.\n\nUse [**mold**](https://github.com/rui314/mold) to speed up the linking. For cmake, you can add link option in `CMakeLists.txt`\n\n```\nadd_link_options(\"-fuse-ld=mold\")\n```\n\nTip: To compile a current dev branch like [coal](https://github.com/coal-library/coal) in a clean conda environment containing just the necessary dependencies, install `compilers` and use conda's `cmake` to ensure compatibility and avoid local dependency conflicts..\n```\nconda create --name ENV_NAME python=3.12\nconda activate ENV_NAME\nconda install -c conda-forge cmake compilers\nconda install coal --only-deps\nmkdir build \u0026\u0026 cd build\ncmake .. -DALL_YOUR_FLAGS\nmake -j8\n```\n\n## Debugging C++ code\n\nIf you execute compiled experimental code or run a python script that is corresponding c++ bindings [Segmentation Faults](https://en.wikipedia.org/wiki/Segmentation_fault). Specific tools can help you to fix them.  \n\n**FIRST: compile in Debug mode**  \n\nUse either gdb (linux) or lldb (macOS). The commands specified below work for both.\n\n### Usage C++\n\n```bash\n# Start debugging session\ngdb \u003cyour-executable\u003e\n\n# set breakpoints in two different ways, either on specific line for function\nb file.cpp:40`\nbreakpoint set -n functionName\n\n# start\nrun\n```\n\nSee [here](https://web.stanford.edu/class/archive/cs/cs107/cs107.1194/resources/gdb) for further details.\n\n### Core dump file analysis\n\nCore dump is another way to debug. First, enable core files\n\n```bash\nulimit -c unlimited\n```\nThen, view the backtrace in gdb\n\n```bash\ngdb path/to/my/executable path/to/coredumpfile\n```\nSee [here](https://askubuntu.com/questions/1349047/where-do-i-find-core-dump-files-and-how-do-i-view-and-analyze-the-backtrace-st) for further details.\n\n### Usage Backward \n\n[Backward](https://github.com/bombela/backward-cpp) is a beautiful stack trace pretty printer for C++. You need to compile your project with generation of debug symbols enabled, usually `-g` with clang++ and g++. Add the following code to the source file\n\n```c++\n#include \u003cbackward.hpp\u003e\nnamespace backward {\n  backward::SignalHandling sh;\n}\n```\n\n### Usage Python bindings\n\n```bash\ngdb python\n# set breakpoints etc.\nrun your_script.py\n```\n\nOnce a program crashes, use `bt` to show the full backtrace.\n\n## Debugging Python code\n\n### Quick-and-dirty one-liner\n\nYou can spawn a Python interpreter in-context anywhere in your code:\n\n```python\n__import__(\"IPython\").embed()\n```\n\nYou may add breakpoints in your Python code using:\n\n```python\nbreakpoint()\n```\n\nFor a better debugger than the basic `pdb` one, you may install [pdb++](https://github.com/pdbpp/pdbpp) using one of the following commands:\n\n```bash\npip install pdbpp # In a pip environment\nconda install -c conda-forge pdbpp # In a Conda environment\n```\n\nWith `pdb++`, add breakpoints again with `breakpoint()`. You may run `sticky` in the pdb++ environment to toggle a sticky mode (with colored code of the whole function) and start a Python interpreter with the `interact` command.\n\nFor debugging code with a graphical interface, check [pudb](https://documen.tician.de/pudb/starting.html) (similar usage).\n\n## Performance analysis with FlameGraph\n\nChecking how much time is spent for every function. Can help you to find the bottleneck in your code.\n[FlameGraph](https://github.com/brendangregg/FlameGraph) is a nice visual tool to display your stack trace.\n\n### Install 1\n\nUse [Rust-powered flamegraph](https://github.com/flamegraph-rs/flamegraph) -\u003e **fast**  \n\n```bash\n# Install tools needed for analysis like perf\nsudo apt-get install linux-tools-common linux-tools-generic linux-tools-`uname -r`\n\n# Install rust on linux or macOS\ncurl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh\n\n# Now you have the rust package managar cargo and you can do\ncargo install flamegraph\n\n# Necessary to allow access to cpu (only once)\necho -1 | sudo tee /proc/sys/kernel/perf_event_paranoid\necho 0 | sudo tee /proc/sys/kernel/kptr_restrict\n\n# Command to produce your flamegraph (use -c for custom options for perf)\nflamegraph -o sparse_wrapper.svg -v -- example-cpp\n```\n\n### Install 2\n\nUse classic perl [flamegraph](https://github.com/brendangregg/FlameGraph)\n\n```bash\n# Install tools needed for analysis like perf\nsudo apt-get install linux-tools-common linux-tools-generic linux-tools-`uname -r`\n\n# Copy the repo\nhttps://github.com/brendangregg/FlameGraph.git\n\n# Necessary to allow access to cpu (only once)\necho -1 | sudo tee /proc/sys/kernel/perf_event_paranoid\necho 0 | sudo tee /proc/sys/kernel/kptr_restrict\n\n# Run perf on your executable and create output repot in current dir\nperf record --call-graph dwarf example-cpp\nperf script \u003e perf.out\n# You can read the report with cat perf.out ..\n\ncd \u003ccloned-flamegraph-repo\u003e\n./stackcollapse-perf.pl \u003clocation-of-perf.out\u003e \u003e out.folded\n./flamegraph.pl out.folded \u003e file.svg\n# Now open the file.svg in your favorite browser in enjoy the interactive mode\n```\n\nAs the process with the default flamegraph repo is quite a pain, you can write your own script like @ManifoldFR in [proxDDP](https://github.com/Simple-Robotics/proxddp/blob/wj/nnl-rollout/scripts/make_flamegraph.sh).\n\n## Performance analysis with Tracy Profiler \nTracy is a real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications that comes with a nice [documentation](https://github.com/wolfpld/tracy/releases/latest/download/tracy.pdf).\nYou can checkout the interactive [demo](https://tracy.nereid.pl/).\n\nTo use it in your project, you can follow the same steps as in pinocchio or simple:\n1. Install it via: `conda install tracy-profiler tracy-profiler-gui -c conda-forge`\n2. Include `tracy.cmake` from jrl-cmakemodules in your main CMakeLists file\n3. Add tracy as project dependency e.g.\n```cmake\nif(PROJECT_NAME_BUILD_WITH_TRACY)\n  # assume it is installed somewhere\n  add_project_dependency(Tracy REQUIRED)\nendif(PROJECT_NAME_BUILD_WITH_TRACY)\n```\n4. In your code: `#include \"project_name/tracy.hpp\"` and use `PROJECT_NAME_TRACY_ZONE_SCOPED_N(\"NAME_OF_ZONE\")` , where project_name should be replaced by your actual project name.\nSee [here](https://github.com/jrl-umi3218/jrl-cmakemodules/blob/b5ae8e49306840a50ae9c752c5b4040f892c89d8/tracy.hh.cmake) for all macros.\n\nAfter specifying the code segments you wish to monitor with Tracy, execute `tracy-profiler` from the command line (ensure your conda environment is active). Run your benchmark files and review the various statistics in the GUI. Note that if you are benchmarking on a remote server, you can connect to it using `ssh user@remote -X` to display the Tracy GUI on your screen.\n\n## Finding memory leaks\n\n[Valgrind](https://valgrind.org/) can automatically detect many memory management and threading bugs.\n\n```\nsudo apt install valgrind\n# Use valgrind with input to check for mem leak\nvalgrind --leak-check=yes myprog arg1 arg2\n```\n\nCheck [here](https://stackoverflow.com/questions/5134891/how-do-i-use-valgrind-to-find-memory-leaks) and [doc](https://valgrind.org/docs/manual/quick-start.html) for further explanation.\n\n[leaks](https://keith.github.io/xcode-man-pages/leaks.1.html) is an alternative tool available on macOS to detect memory leaks:\n```\n$ leaks -atExit -- myprog\n\nDate/Time:       2024-07-17 17:46:43.948 +0200\nLaunch Time:     2024-07-17 17:46:42.781 +0200\nOS Version:      macOS 14.5 (23F79)\nReport Version:  7\nAnalysis Tool:   Xcode.app/Contents/Developer/usr/bin/leaks\nAnalysis Tool Version:  Xcode 15.4 (15F31d)\n\nPhysical footprint:         4646K\nPhysical footprint (peak):  4646K\nIdle exit:                  untracked\n----\n\nleaks Report Version: 4.0, multi-line stacks\nProcess 56686: 507 nodes malloced for 47 KB\nProcess 56686: 0 leaks for 0 total leaked bytes.\n```\nCheck out [here](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/FindingLeaks.html) for more information.\n\n\n### AddressSanitizer\n\n[AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) (aka ASan) is a memory error detector for C/C++. For cmake, you can add link option in `CMakeLists.txt`\n\n```\nset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fsanitize=address\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fsanitize=address\")\n```\n\n## Check Eigen malloc\n\nUse Eigen tools to make sure you are not allocating memory where you do not want to do so -\u003e it is slowing down your program. Check [proxqp](https://github.com/Simple-Robotics/proxsuite/blob/794607d4e35626fc4d5bb704f4f1796347412e71/include/proxsuite/fwd.hpp#L40) or [here](https://stackoverflow.com/questions/33664976/avoiding-eigens-memory-allocation).  \n\nThe macros defined in `ProxQP` allow us to do\n\n```cpp\nPROXSUITE_EIGEN_MALLOC_NOT_ALLOWED();\noutput = superfast_function_without_allocations();\nPROXSUITE_EIGEN_MALLOC_ALLOWED();\n```\n\nand if this code is compiled in `Debug` mode, we will have assertation errors if eigen is allocation memory inside the function.\n\n## Checking for memory alloctions\n\nGUI to check how much memory is allocated in every function when executing a program.  \n-\u003e Valgrind + [KCachegrind](https://github.com/KDE/kcachegrind)\n\n### Install\n\n`sudo apt-get install valgrind kcachegrind graphviz`\n\n### Usage\n\n```bash\nvalgrind --tool=massif --xtree-memory=full \u003cyour-executable\u003e\nkcachegrind \u003coutput-file-of-previous-cmd\u003e\n```\n\n## Performance analysis in Python\n\nPython provides a profiler named [cProfile](https://docs.python.org/3/library/profile.html). To profile a script, simply add `-m cProfile -o profile.prof` when running the script, i.e.:\n\n```bash\npython -m cProfile -o profile.prof my_script.py --my_args\n```\n\nThis saves the result in the specified output path (here, `profile.txt`), which you can then visualize with snakeviz: `pip install snakeviz` and then:\n\n```bash\nsnakeviz profile.prof\n```\n\nThis opens a browser tab with an interactive visualization of execution times.\n\n## External resources\n\nSome very [useful advices to optimize your C++ code that you should have in mind](https://cpp-optimizations.netlify.app/).\n\n\u003e Narrator: \"also quite amusing to read...\"\n\nA nice online course to [get started with C++](https://gitlab.inria.fr/formations/cpp/gettingstartedwithmoderncpp/tree/master) explaining most of the basic concepts in c++14/17.\n\n## Debug GitHub CI (SSH)\n\nIf your GitHub Actions pipeline fails and you want to inspect the environment directly, you can open an SSH session with [action-tmate](https://github.com/mxschmitt/action-tmate). It launches an interactive terminal in your job, allowing real-time debugging.\n\n1. Add this step at the point where you want the workflow to pause:\n  ```yaml\n  - name: Start SSH session\n    uses: mxschmitt/action-tmate@v3\n    with:\n      limit-access-to-actor: true\n  ```\n2. Run the CI\n3. An SSH connection command will appear in the workflow log for you to copy and run in your terminal.\n\n**Tip:** the option `continue-on-error: true` can be helpful since you’ll often want to investigate a previous step that failed. It prevents the workflow from stopping immediately on error and allows it to continue to your SSH step so you can connect and debug the environment.\n\n**Note:** `limit-access-to-actor: true` means that only the GitHub user who triggered the workflow can connect — using an SSH key already registered on their GitHub account.\n\nAlternative:\n* [lhotari/action-upterm](https://github.com/lhotari/action-upterm) provides similar functionality.\n* [debug-via-ssh](https://github.com/marketplace/actions/debug-via-ssh) is **not recommended** since it relies on [ngrok](https://ngrok.com/) which requires credit card information to function.\n\n## Profile C++ compile time of a translation unit\n\nWhen doing heavy template meta-programming in C++ it can be useful to analyze what part of the code is taking a long time to compile.\n\n[clang](https://clang.llvm.org) allows to profile the compilation time of a translation unit. To activate this function, add the `-ftime-trace` option while building.\n\nIn a CMake project, you can do this with the following command line:\n\n```bash\ncmake .. -DCMAKE_CXX_FLAGS=\"-ftime-trace\"\n```\n\nEach .cpp will then produce a .json file. To find them you can use the following command line:\n\n```bash\nfind . -iname \"*.json\"\n```\n\nThen, you can open the file with the [Chromium tracing tool](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool/). Open the `about:tracing` URL in Chromium and load the .json. You will have the following display:\n\n![Compile time translation unit profile displayed with Chromimum](./resources/cpp-compilation-time-profile.png)\n\n### Note for GNU/Linux users\n\n`-ftime-trace` is only available with [clang](https://clang.llvm.org). With [conda](https://docs.conda.io/en/latest/), you can install it with the following command line `conda install clangxx`.\n\nThen, when running CMake **for the first time** use the following command:\n\n```bash\nCC=clang CXX=clang++ cmake ..\n```\n\n\n## Profile C++ compile time of a CMake target\n\nWhen building a CMake target, it's interesting to profile which translation unit took most of the compile time.\n\nNinja and [ninjatracing](https://github.com/nico/ninjatracing) allow to do visualize the whole target build time.\n\nFirst clone [ninjatracing](https://github.com/nico/ninjatracing) somewhere.\n\nThen configure your CMake build to use Ninja. Run the following command in a **NEW** build directory:\n\n```bash\ncmake .. -GNinja\n```\n\nNow, build your project with Ninja:\n\n```bash\nninja\n```\n\nThe `.ninja_log` file should had been created in the build directory.\nYou can convert it to a file compatible with the [Chromium tracing tool](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool/).\n\nRun the following command:\n\n```bash\npath/to/ninjatracing .ninja_log \u003e trace.json\n```\n\nNow, you can visualize it with the [Chromium tracing tool](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool/). Open the `about:tracing` URL in Chromium and load the .json. You will have the following display:\n\n![Compile time CMake target profile displayed with Chromimum](./resources/cpp-cmake-target-compilation-time-profile.png)\n\n\n## Launch a process on a particular CPU/CORE/PU\n\n[hwloc tools](https://www.open-mpi.org/projects/hwloc/) allow to study computer and computer cluster topology.\n\nTo install `hwloc` on ubuntu, run the following `apt` command:\n\n```bash\nsudo apt install hwloc\n```\n\nYou can show your computer architecture topology with:\n\n```bash\nlstopo\n```\n\nAlso, you can run a process on a particular CPU/CORE/PU with the following command:\n\n```bash\n# Run my_exe on processing unit 0\nhwloc-bind pu:0 -- my_exe\n# Run my_exe on core 2\nhwloc-bind pu:2 -- my_exe\n```\n\nYou can then watch where processes are running with:\n\n```bash\nlstopo --ps\n```\n\nTo go deeper, a [tutorial](https://www.open-mpi.org/projects/hwloc/tutorials/20120702-POA-hwloc-tutorial.html) is available.\n\n## Get stack size\n\nThe stack of a program is limited in memory space available. One way to get this value is to run in your favorite terminal:\n\n```bash \nulimit -s\n```\n\nMore information on the current configuration can be obtained via:\n\n```bash\nulimit -a\n```\n\n## Counting number of lines of codes\n\nIt might be useful at some point to count the number of lines of code in a given project.\n[Cloc](https://github.com/AlDanial/cloc) is an open-source tool that counts blank lines, comment lines, and physical lines of source code in many programming languages. \n\nIn [Pinocchio](https://github.com/stack-of-tasks/pinocchio), counting the important lines of code can be done using:\n\n```bash\ncloc unittest src include examples bindings \n```\n\nwhich gives:\n```\n    3149 text files.\n    2299 unique files.                                          \n     970 files ignored.\n\ngithub.com/AlDanial/cloc v 2.04  T=0.90 s (2543.7 files/s, 395546.2 lines/s)\n--------------------------------------------------------------------------------\nLanguage                      files          blank        comment           code\n--------------------------------------------------------------------------------\nC/C++ Header                    672          20927          20408         107549\nC++                             423          15686           4418          61598\nXML                             154            101            120          53449\nCMake                           325           2595           4955          18197\nPython                          214           4459           2277          15361\nmake                             13           2073           1463           4100\nINI                             100            657              0           4047\nMarkdown                         71            976             40           2509\nText                             89            231              0           1444\nCSS                               4            138             57            549\nYAML                             10             48             10            519\nBourne Shell                      4             83            167            444\nSVG                               1              1              1            382\nJupyter Notebook                  1              0            655            214\nJavaScript                      196            196           3332            196\nTeX                               5              0              0            167\nreStructuredText                  8            102             83            147\nHTML                              4              1             25             92\nObjective-C                       1             11             16             92\nJSON                              1              0              0             46\nBourne Again Shell                2             14             12             45\nawk                               1              0              0             10\n--------------------------------------------------------------------------------\nSUM:                           2299          48299          38039         271157\n--------------------------------------------------------------------------------\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimple-robotics%2Fcode-analysis-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimple-robotics%2Fcode-analysis-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimple-robotics%2Fcode-analysis-tools/lists"}