|
1 | 1 | # <img src="https://raw.githubusercontent.com/nim-lang/assets/master/Art/logo-crown.png" height="28px"/> Nim |
2 | 2 |
|
| 3 | +## Notice for this special version -> v2.0.12 with Heaptrack support |
| 4 | +# Heaptrack for Nim |
| 5 | + |
| 6 | +This branch allows you to use [heaptrack](https://github.com/KDE/heaptrack) on nim programs. |
| 7 | + |
| 8 | +## Heaptrack |
| 9 | +Heaptrack is a neat little tool used for RAM usage debugging, allowing to find leaks, allocation hotspots, etc. |
| 10 | + |
| 11 | +It's usable in two ways: |
| 12 | +- Preload: ex, `heaptrack ls`, will preload `libheaptrack_preload.so` into ls, and record every allocation during the entire program |
| 13 | +- Inject: ex, `ls &; heaptrack -p $(pidof ls)`, will attach to the running program using `gdb`, inject `libheaptrack_inject.so`, and record every allocation from this point until the program finishes or `heaptrack` is killed. |
| 14 | + |
| 15 | +Preload is more useful for short-running application, and allow to detect memory leaks as well. |
| 16 | + |
| 17 | +Inject is useful to monitor a precise moment of a long running application, and can't detected memory leaks (since the program could `free` the allocated memory after we've detached, or have `alloc`ated before we attached) |
| 18 | + |
| 19 | +Internally, `heaptrack` works by writing into a file each allocation and dellocation done by the program, along with the stacktrace for each allocation, eg: |
| 20 | + |
| 21 | +``` |
| 22 | ++ 55c7e2ff17ea 15 #Allocated 21 bytes into address "55c7e2ff17ea" |
| 23 | +- 55c7e2ff17ea #Deallocated pointer "55c7e2ff17ea" |
| 24 | +``` |
| 25 | +(note, this is a simplification of the actual format, which is optimized to be machine-readable but not human readable) |
| 26 | + |
| 27 | +For most of programs, it just wraps `malloc` and `free` into custom function to create this file, but obviously, nim doesn't use `malloc` and `free`, so some trickery is required. |
| 28 | + |
| 29 | +## Heaptrack in Nim |
| 30 | +This branch simply plugs the `libheaptrack`'s procs into the nim gc, allowing to use heaptrack for nim programs. |
| 31 | +```bash |
| 32 | +nim c -d:heaptracker test.nim |
| 33 | +heaptrack ./test #works as any program |
| 34 | +``` |
| 35 | + |
| 36 | +Be careful, to use the `inject` mode, the `libheaptrack_inject.so` must be used instead of `libheaptrack_preload.so` during compilation: |
| 37 | +```bash |
| 38 | +nim c -d:heaptracker -d:heaptracker_inject test.nim |
| 39 | +LD_LIBRARY_PATH=/usr/local/lib/heaptrack ./test & |
| 40 | +heaptrack -p $(pidof test) |
| 41 | +``` |
| 42 | +The binary must use the same `.so` as `heaptrack`, so an `inject` binary won't work with `prelude`, and a `prelude` binary won't work with `inject` |
| 43 | + |
| 44 | +Be also careful, once a binary has been compiled with `-d:heaptracker`, it won't run on a device where `heaptrack` is not installed. |
| 45 | +For `inject`, you also need to specify the `LD_LIBRARY_PATH` to locate the `so` files. |
| 46 | + |
| 47 | +## Heaptrack for Nimbus |
| 48 | +To build nimbus with heaptrack enabled: |
| 49 | +Add to the Makefile the required flags, as [shown here](https://github.com/status-im/nimbus-eth2/commit/90eca6d54309db669f03866fb8d432b739687f70) |
| 50 | + |
| 51 | +Change to build Dockerfile to add `apt install heaptrack` and set the `LD_LIBRARY_PATH` properly |
| 52 | + |
| 53 | +Add `gdb` capabilities to the docker-compose.yml |
| 54 | +```yaml |
| 55 | + cap_add: |
| 56 | + - 'SYS_PTRACE' |
| 57 | + security_opt: |
| 58 | + - 'seccomp:unconfined' |
| 59 | +``` |
| 60 | +
|
| 61 | +Once everything is setup, you can go into the container, install gdb, and run `heaptrack -p 1` as usual. |
| 62 | +When you're happy with your capture, stop heaptrack, retrieve the file on your computer for analysis, and voilà! |
| 63 | + |
| 64 | + |
| 65 | + |
| 66 | + |
| 67 | + |
3 | 68 | [](https://dev.azure.com/nim-lang/Nim/_build/latest?definitionId=1&branchName=devel) |
4 | 69 |
|
5 | 70 | This repository contains the Nim compiler, Nim's stdlib, tools, and documentation. |
|
0 commit comments