Add heaptrack support (#25257)

This PR, courtesy of @NagyZoltanPeter
(https://github.com/waku-org/nwaku/pull/3522) adds the ability to track
memory allocations in a program suitable for use with
[heaptrack](https://github.com/KDE/heaptrack).

By passing `-d:heaptrack --debugger:native` to compilation, calls to
heaptrack will be injected when memory is being allocated and released -
unlike `-d:useMalloc` this strategy also works with `refc` and the
default memory pool.

See https://github.com/KDE/heaptrack for usage examples. The resulting
binary needs to be run with `heaptrack` and with the shared
`libheaptrack_preload.so` in the `LD_LIBRARY_PATH`.
This commit is contained in:
Jacek Sieka
2025-11-06 17:33:52 +01:00
committed by araq
parent 116c220e3f
commit 155b06a4f5
2 changed files with 15 additions and 0 deletions

View File

@@ -580,6 +580,8 @@ Define Effect
Currently only clang and vcc.
`strip` Strip debug symbols added by the backend compiler from
the executable.
`heaptrack` Track memory allocations using
[heaptrack](https://github.com/KDE/heaptrack)
====================== =========================================================

View File

@@ -837,6 +837,15 @@ when defined(gcDestructors):
dec maxIters
if it == nil: break
when defined(heaptrack):
const heaptrackLib =
when defined(heaptrack_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)
@@ -959,6 +968,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(heaptrack):
heaptrack_malloc(result, requestedSize)
proc rawAlloc0(a: var MemRegion, requestedSize: int): pointer =
result = rawAlloc(a, requestedSize)
@@ -967,6 +978,8 @@ proc rawAlloc0(a: var MemRegion, requestedSize: int): pointer =
proc rawDealloc(a: var MemRegion, p: pointer) =
when defined(nimTypeNames):
inc(a.deallocCounter)
when defined(heaptrack):
heaptrack_free(p)
#sysAssert(isAllocatedPtr(a, p), "rawDealloc: no allocated pointer")
sysAssert(allocInv(a), "rawDealloc: begin")
var c = pageAddr(p)