Hi All,
I am doing analysis on memory leak for the create/delete configuration and get-config opertation.
What I observed is when deleting the interface in node, the below memory leak was observed and 67 bytes of memory are lost when committed the deletion of a single interface.
From the call stack below, it goes to confd lib call stack ,
Could you please give your comments why this leak was observed and how to
resolve this memory leak?
==18304== 67 bytes in 1 blocks are definitely lost in loss record 20,085 of 34,746
==18304== at 0x4005C18: malloc (vg_replace_malloc.c:270)
==18304== by 0x43ADBA5: wrapped_malloc (WrappedAllocator.c++:190)
==18304== by 0x9724A3E: malloc (MallocLeakDetect.c++:112)
==18304== by 0x44A4F3B7: strdup (strdup.c:42)
==18304== by 0x4034BEF: _confd_vset_error (confd_lib.c:3231)
==18304== by 0x40388BD: confd_trans_seterr (confd_lib.c:5834)
==18304== by 0x966EF35: ConfDInterface::RemoveElement(confd_trans_ctx*, confd_hkeypath*, session&) (ConfDInterface.c++:2416)
Hi All,
Could you please help on the query which I raised.
Do we need to free anything from our side other than confd perspective when call hits confd_trans_seterr ?
I assume transaction for which you have set the error (via confd_trans_seterr()) was not finished/terminated properly.
(which is the point where would be released, or on repeated call to confd_trans_seterr())
if you have new transaction opened explicitly by yourself, you may be missing e.g. maapi_finish_trans()
if this is for some callback registered with confd, you may be terminating app during the running transaction and miss some âdestructorâ work that would close/finish the transaction from appâs point of viewâŚ
So question is what leads to your scenario -> do you have some sockets closed, network connectivity interruptions, app crash, etc.?
Hi Joseph,
The scenario is,
I have created one interface and delete the same interface. Then I collected the valgrind logs and seen some approx 67 bytes were lost. Basically I am checking for memory leak for create/delete/GET operation
There is no crash or socket closed issue observed. Only the leak is the issue here.
And the call stack is below for the scenario,
==18304== 67 bytes in 1 blocks are definitely lost in loss record 20,085 of 34,746
==18304== at 0x4005C18: malloc (vg_replace_malloc.c:270)
==18304== by 0x43ADBA5: wrapped_malloc (WrappedAllocator.c++:190)
==18304== by 0x9724A3E: malloc (MallocLeakDetect.c++:112)
==18304== by 0x44A4F3B7: strdup (strdup.c:42)
==18304== by 0x4034BEF: _confd_vset_error (confd_lib.c:3231)
==18304== by 0x40388BD: confd_trans_seterr (confd_lib.c:5834)
==18304== by 0x966EF35: ConfDInterface::RemoveElement(confd_trans_ctx*, confd_hkeypath*, session&) (ConfDInterface.c++:2416)
valgrind shows that call to confd_trans_seterr() has been done in your code
this supposedly allocates some memory
this memory is freed either on:
next call to confd_trans_seterr()
(this of course means it allocates new memory for new call, but it also means that there is no growing leak)
(X) when transaction is closed/terminated properly
(user finishes norhtbound session / or, if you opened it in your app the code finishes transaction via finish callâŚ
valgrind complains that there is âmem-leakâ, which means that app was terminated (as valgrind prints leak info on app termination) before (X) happened.
(confd-lib never got chance (or reason) to clear memory properly)
Hi Joseph,
I will try to summarize the leak and when it hits. Based on that please give your comments.
Usecase Steps :
Create one Interface and delete the same interface
The confd trace logs shows interface got deleted and transaction was finished.
2020-11-05 23:24:32:084 TRACE CALL data delete(thandle=39,/interfaces/interface{itf.0})2020-11-05 23:24:32:084 --> CONFD_ACCUMULATE
2020-11-05 23:24:32:084 TRACE CALL trans prepare(thandle=39)2020-11-05 23:24:32:512 --> CONFD_OK
2020-11-05 23:24:32:515 TRACE CALL trans commit(thandle=39)2020-11-05 23:24:32:516 --> CONFD_OK
2020-11-05 23:24:32:516 TRACE CALL trans finish(thandle=39)2020-11-05 23:24:32:517 --> CONFD_OK
Then I killed the process to collect valgrind logs, there I have seen the leak of 67 bytes.
==18304== 67 bytes in 1 blocks are definitely lost in loss record 20,085 of 34,746
==18304== at 0x4005C18: malloc (vg_replace_malloc.c:270)
==18304== by 0x43ADBA5: wrapped_malloc (WrappedAllocator.c++:190)
==18304== by 0x9724A3E: malloc (MallocLeakDetect.c++:112)
==18304== by 0x44A4F3B7: strdup (strdup.c:42)
==18304== by 0x4034BEF: _confd_vset_error (confd_lib.c:3231)
==18304== by 0x40388BD: confd_trans_seterr (confd_lib.c:5834)
==18304== by 0x966EF35: ConfDInterface::RemoveElement(confd_trans_ctx*, confd_hkeypath*, session&) (ConfDInterface.c++:2416)
From the ConfD UG (that has been quoted many times before):
When debugging application memory leaks with a tool like valgrind, it is often necessary to rebuild libconfd from source, since the default build uses a âpool allocatorâ that makes the stack trace information for memory leaks from valgrind completely misleading for allocations from libconfd. The details of how to do a build that disables the pool allocator are described in the âApplication debuggingâ section of the README in the libconfd source package
âŚand from the âlibconfd source packageâ README:
When debugging application memory leaks with a tool like âvalgrindâ, and
the stack trace information from âvalgrindâ indicates that memory
allocated by libconfd has not been freed, it is necessary to rebuild
libconfd from source, since the default build uses a âpool allocatorâ
that makes the stack trace information for libconfd completely
misleading.
To build a version of libconfd that disables the pool allocator, the
environment variable $NO_FIX_ALLOC must be set to âyesâ before building
from a freshly unpacked tar archive - running âmake cleanâ after an
earlier build is not sufficient. I.e. proceed as follows:
Unpack the tar archive.
Do âexport NO_FIX_ALLOC=yesâ in the shell.
Build as described above.
Note that the libconfd performance may be degraded when the pool
allocator is disabled - i.e. such a build should only be used for
debugging.