Closed traversaro closed 3 months ago
The MemoryAllocationMonitor
is inspired by the code added in YARP in https://github.com/robotology/yarp/pull/365, the main difference is that that code only intercepted memory allocation done via C++'s new
, while by overloading malloc
we can detect also code that is not allocating memory via new
.
cc @giotherobot @rozzong if you need to automatically monitor in a test if a piece of code perform dynamic memory allocation, you can refer to the code in this PR.
The vcpkg/CI job failure is not related to the PR, see https://github.com/ami-iit/bipedal-locomotion-framework/issues/769 .
The vcpkg/CI job failure is not related to the PR, see #769 .
Instead the apt failure is related, for some reason what is working with conda compilers is failing on apt on Ubuntu 20.04 .
The vcpkg/CI job failure is not related to the PR, see #769 .
Instead the apt failure is related, for some reason what is working with conda compilers is failing on apt on Ubuntu 20.04 .
I think the issue was in glibc, not in the compilers. Anyhow, it seems that everything works fine if we link the library to preload with -ldl
(that make sense as we actually use dlsym
). Probably just with the glibc of Ubuntu 22.04 calling dlsym
resulted in a dynamic loader looking for the symbol, resulting in a malloc call that itself created an infinite recursive call to malloc
.
The vcpkg/CI job failure is not related to the PR, see #769 .
Instead the apt failure is related, for some reason what is working with conda compilers is failing on apt on Ubuntu 20.04 .
I think the issue was in glibc, not in the compilers. Anyhow, it seems that everything works fine if we link the library to preload with
-ldl
(that make sense as we actually usedlsym
). Probably just with the glibc of Ubuntu 22.04 callingdlsym
resulted in a dynamic loader looking for the symbol, resulting in a malloc call that itself created an infinite recursive call tomalloc
.
Actually, this was just luck, other tests still fail with a infinite recursive calls. Probably we need some kind of dummy allocator as done in heaptrack: https://github.com/KDE/heaptrack/blob/0f5285ce7ba7dfe45a937398cbd88ffc29dfe828/src/track/heaptrack_preload.cpp#L158 .
The vcpkg/CI job failure is not related to the PR, see #769 .
Instead the apt failure is related, for some reason what is working with conda compilers is failing on apt on Ubuntu 20.04 .
I think the issue was in glibc, not in the compilers. Anyhow, it seems that everything works fine if we link the library to preload with
-ldl
(that make sense as we actually usedlsym
). Probably just with the glibc of Ubuntu 22.04 callingdlsym
resulted in a dynamic loader looking for the symbol, resulting in a malloc call that itself created an infinite recursive call tomalloc
.Actually, this was just luck, other tests still fail with a infinite recursive calls. Probably we need some kind of dummy allocator as done in heaptrack: https://github.com/KDE/heaptrack/blob/0f5285ce7ba7dfe45a937398cbd88ffc29dfe828/src/track/heaptrack_preload.cpp#L158 .
I tried to fix this, but it is not trivial. I guess an easier option is just to run the tests on system with glibc >= 2.35, I did this in https://github.com/ami-iit/bipedal-locomotion-framework/pull/768/commits/8a10a1888c42422165b59138afda5e13e7ee5063 and I think this should fix the CI.
After limiting the check on glibc >= 2.35 systems, the only remaining failing jobs are due to https://github.com/ami-iit/bipedal-locomotion-framework/issues/769 .
Hi @traversaro, I don't remember the status of this PR. Do you think it is mergeable?
Hi @traversaro, I don't remember the status of this PR. Do you think it is mergeable?
I just solved the conflicts, if the CI is happy it is good to go.
Let me rebase the PR on master.
This PR adds a
MemoryAllocationMonitor
class that part of a non-installed TestUtils library.The
MemoryAllocationMonitor
class can be used to test if a portion of code is allocating (or de-allocating) memory dynamically, with the following structure:The
MemoryAllocationMonitor
monitors memory allocation by overloadingmalloc
and other memory allocation functions in thesrc/TestUtils/MemoryAllocationMonitorRedefinedMemoryFunctions.c
. This function are contained in a small shared-only library calledMemoryAllocationMonitorPreload
, that is then injected in the tests viaLD_PRELOAD
(see the logic incmake/AddBipedalLocomotionUnitTest.cmake
).These redefined functions are just incrementing a counter for each call, and then call the regular non-redefined functions. The counter are reset by the
MemoryAllocationMonitor::startMonitor()
function.MemoryAllocationMonitor::endMonitorAndCheckNoMemoryAllocationInLastMonitor()
returns true if all counter are still zero, and false otherwise.As demonstrated in the
src/TestUtils/tests/MemoryAllocationMonitorTest.cpp
test, this strategy is able to detect reliably allocation done via C's malloc, C++'s new, std's containers or Eigen vectors.Redefining
malloc
and injecting it viaLD_PRELOAD
only works on Linux, so all the machinery is only present if the CMake optionFRAMEWORK_RUN_MemoryAllocationMonitor_tests
is enabled (that is enabled by default only on Linux). IfFRAMEWORK_RUN_MemoryAllocationMonitor_tests
isOFF
, a dummy version ofMemoryAllocationMonitor
is compiled whereMemoryAllocationMonitor::endMonitorAndCheckNoMemoryAllocationInLastMonitor()
always returntrue
, so that we can avoid to modify the tests code.To add an example of usage of this new class, I added tests of non-allocation of memory in the
advance
portion of ContinuousDynamicalSystem tests. Apparently theIntegrator
class allocates some memory in the first run of theadvance
method, so I had to account for that and only do the checksEventually I may include this functionality in self-contained easy to re-use library, but I wanted first to start with a more simple example.