chore: Adapt heaptrack support builds and description to latest nim 2.2.4 compiler (#3522)

* Adapt heaptrack support builds and description to latest nim 2.2.4 compiler
This commit is contained in:
NagyZoltanPeter 2025-08-29 08:10:22 +02:00 committed by GitHub
parent 6e976f7f29
commit 01f1384a01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 81 additions and 10 deletions

View File

@ -5,6 +5,7 @@ ARG NIMFLAGS
ARG MAKE_TARGET=wakunode2
ARG NIM_COMMIT
ARG LOG_LEVEL=TRACE
ARG HEAPTRACK_BUILD=0
# Get build tools and required header files
RUN apk add --no-cache bash git build-base openssl-dev linux-headers curl jq
@ -18,6 +19,10 @@ RUN apk update && apk upgrade
# Ran separately from 'make' to avoid re-doing
RUN git submodule update --init --recursive
RUN if [ "$HEAPTRACK_BUILD" = "1" ]; then \
git apply --directory=vendor/nimbus-build-system/vendor/Nim docs/tutorial/nim.2.2.4_heaptracker_addon.patch; \
fi
# Slowest build step for the sake of caching layers
RUN make -j$(nproc) deps QUICK_AND_DIRTY_COMPILER=1 ${NIM_COMMIT}

View File

@ -95,10 +95,8 @@ NIM_PARAMS := $(NIM_PARAMS) -d:git_version=\"$(GIT_VERSION)\"
HEAPTRACKER ?= 0
HEAPTRACKER_INJECT ?= 0
ifeq ($(HEAPTRACKER), 1)
# Needed to make nimbus-build-system use the Nim's 'heaptrack_support' branch
DOCKER_NIM_COMMIT := NIM_COMMIT=heaptrack_support_v2.0.12
# Assumes Nim's lib/system/alloc.nim is patched!
TARGET := debug-with-heaptrack
NIM_COMMIT := heaptrack_support_v2.0.12
ifeq ($(HEAPTRACKER_INJECT), 1)
# the Nim compiler will load 'libheaptrack_inject.so'
@ -351,6 +349,7 @@ docker-image:
--build-arg="NIMFLAGS=$(DOCKER_IMAGE_NIMFLAGS)" \
--build-arg="NIM_COMMIT=$(DOCKER_NIM_COMMIT)" \
--build-arg="LOG_LEVEL=$(LOG_LEVEL)" \
--build-arg="HEAPTRACK_BUILD=$(HEAPTRACKER)" \
--label="commit=$(shell git rev-parse HEAD)" \
--label="version=$(GIT_VERSION)" \
--target $(TARGET) \
@ -359,6 +358,7 @@ docker-image:
docker-quick-image: MAKE_TARGET ?= wakunode2
docker-quick-image: DOCKER_IMAGE_TAG ?= $(MAKE_TARGET)-$(GIT_VERSION)
docker-quick-image: DOCKER_IMAGE_NAME ?= wakuorg/nwaku:$(DOCKER_IMAGE_TAG)
docker-quick-image: NIM_PARAMS := $(NIM_PARAMS) -d:chronicles_colors:none -d:insecure -d:postgres --passL:$(LIBRLN_FILE) --passL:-lm
docker-quick-image: | build deps librln wakunode2
docker build \
--build-arg="MAKE_TARGET=$(MAKE_TARGET)" \

View File

@ -33,20 +33,33 @@ It operates in two modes:
- `sudo apt install libkf5kio-dev`
- `sudo apt install libkf5iconthemes-dev`
- `make`
- On completion, the `bin/heaptrack_gui` and `bin/heaptrack` binaries will get generated.
- On completion, the `bin/heaptrack_gui` and `bin/heaptrack` binaries will be generated.
- heaptrack: needed to generate the report.
- heaptrack_gui: needed to analyse the report.
## Heaptrack & Nwaku
nwaku supports heaptrack but it needs a special compilation setting.
nwaku supports heaptrack, but it needs a special compilation setting.
### Patch Nim compiler to register allocations on Heaptrack
Currently, we rely on the official Nim repository. So we need to patch the Nim compiler to register allocations and deallocations on Heaptrack.
For Nim 2.2.4 version, we created a patch that can be applied as:
```bash
git apply --directory=vendor/nimbus-build-system/vendor/Nim docs/tutorial/nim.2.2.4_heaptracker_addon.patch
git add .
git commit -m "Add heaptrack support to Nim compiler - temporary patch"
```
> Until heaptrack support is not available in official Nim, so it is important to keep it in the `nimbus-build-system` repository.
> Commit ensures that `make update` will not override the patch unintentionally.
> We are planning to make it available through an official PR for Nim.
When the patch is applied, we can build wakunode2 with heaptrack support.
### Build nwaku with heaptrack support
The make command should have the 'NIM_COMMIT' setting as:
`make -j<nproc> NIM_COMMIT=heaptrack_support ...`
This is to force the `nimbus-build-system` to use the Nim compiler that points at the [heaptrack_support](https://github.com/status-im/nim/tree/heaptrack_support) branch.
`make -j<nproc> HEAPTRACKER=1 wakunode2`
### Create nwaku memory report with heaptrack
@ -69,9 +82,18 @@ Having Docker properly installed in your machine, do the next:
- cd to the `nwaku` root folder.
- ```sudo make docker-image DOCKER_IMAGE_NAME=docker_repo:docker_tag HEAPTRACKER=1```
- alternatively you can use the `docker-quick-image` target, this is faster but creates an ubuntu based image, so your local build environment must match.
That will create a Docker image with both nwaku and heaptrack. The container's entry point is `ENTRYPOINT ["/heaptrack/build/bin/heaptrack", "/usr/bin/wakunode"]`, so the memory report starts being generated from the beginning.
#### Notice for using heaptrack supporting image with `docker compose`
Take care that wakunode2 should be started as
```
exec /heaptrack/build/bin/heaptrack /usr/bin/wakunode\
... all the arguments you want to pass to wakunode ...
```
### Extract report file from a running Docker container
Bear in mind that if you restart the container, the previous report will get lost. Therefore, before restarting, it is important to extract it from the container once you consider it has enough information.

View File

@ -0,0 +1,44 @@
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index e2dd43075..7f8c8e04e 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -1,4 +1,4 @@
-#
+#!fmt: off
#
# Nim's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
@@ -862,6 +862,15 @@ when defined(gcDestructors):
dec maxIters
if it == nil: break
+when defined(heaptracker):
+ const heaptrackLib =
+ when defined(heaptracker_inject):
+ "libheaptrack_inject.so"
+ else:
+ "libheaptrack_preload.so"
+ proc heaptrack_malloc(a: pointer, size: int) {.cdecl, importc, dynlib: heaptrackLib.}
+ proc heaptrack_free(a: pointer) {.cdecl, importc, dynlib: heaptrackLib.}
+
proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
when defined(nimTypeNames):
inc(a.allocCounter)
@@ -984,6 +993,8 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
sysAssert(isAccessible(a, result), "rawAlloc 14")
sysAssert(allocInv(a), "rawAlloc: end")
when logAlloc: cprintf("var pointer_%p = alloc(%ld) # %p\n", result, requestedSize, addr a)
+ when defined(heaptracker):
+ heaptrack_malloc(result, requestedSize)
proc rawAlloc0(a: var MemRegion, requestedSize: int): pointer =
result = rawAlloc(a, requestedSize)
@@ -992,6 +1003,8 @@ proc rawAlloc0(a: var MemRegion, requestedSize: int): pointer =
proc rawDealloc(a: var MemRegion, p: pointer) =
when defined(nimTypeNames):
inc(a.deallocCounter)
+ when defined(heaptracker):
+ heaptrack_free(p)
#sysAssert(isAllocatedPtr(a, p), "rawDealloc: no allocated pointer")
sysAssert(allocInv(a), "rawDealloc: begin")
var c = pageAddr(p)