Discussion:
Memory leak in inetCidrRouteTable 5.7.3
Soubhagya Panigrahi
2016-11-07 13:55:49 UTC
Permalink
Hi All,

I have some queries with respect to memory leak in inetCidrRouteTable while
continuous query to inetCidrRouteTable .

Valgrind report
===============

7480 ==16547== 7,569,856 bytes in 3,416 blocks are definitely lost in loss
record 5,344 of 5,344
7481 ==16547== at 0x4C266B0: calloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
7482 ==16547== by 0x475E04: inetCidrRouteTable_allocate_rowreq_ctx
(snmp/subagent/inetCidrRouteTable_interface.c:584)
7483 ==16547== by 0x47427A: add_ipv6_route_entries
(snmp/subagent/inetCidrRouteTable_data_access.c:792)
7484 ==16547== by 0x474856: inetCidrRouteTable_container_load
(snmp/subagent/inetCidrRouteTable_data_access.c:693)
7485 ==16547== by 0x52B83F4: _cache_load (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7486 ==16547== by 0x52B8F9C: netsnmp_cache_helper_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7487 ==16547== by 0x52CC2F6: netsnmp_call_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7488 ==16547== by 0x52C048C: table_helper_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7489 ==16547== by 0x52CD25E: netsnmp_call_handlers (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7490 ==16547== by 0x52D6880: handle_var_requests (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7491 ==16547== by 0x52D7ABF: handle_getnext_loop (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7492 ==16547== by 0x52DA8FF: netsnmp_handle_request (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7493 ==16547== by 0x52DB3D9: handle_snmp_packet (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7494 ==16547== by 0x574A217: ??? (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7495 ==16547== by 0x574ABF6: _sess_read (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7496 ==16547== by 0x574BA38: snmp_sess_read2 (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7497 ==16547== by 0x574BAFA: snmp_read2 (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7498 ==16547== by 0x574BB43: snmp_read (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7499 ==16547== by 0x430C7A: agent_check_and_process_mutex
(snmp/subagent/cwoAoStatsTable_subag

As part of my project, we have added a support for ipv6 route entry in
"add_ipv6_route_entries()" under inetCidrRouteTable_container_load().

Allocating memory is same, how it is being done in
"inetCidrRouteTable_container_load()". But as per valgrind report, Leak is
showing in newly implemented add_ipv6_route_entries() code not in
inetCidrRouteTable_container_load(). So it is obvious that memory
deallocation part is not being implemenetd properly.

here my question is where and how to free the newly allocated memory . The
reason why I am asking in this forum is whether to call release request or
need to check how can i use CONTAINER_FREE for this.

I could see, for inetCidrRouteTable_container_load, there is one respective
"inetCidrRouteTable_release_rowreq_ctx(rowreq_ctx)" to free the memory
called by _cache_free() which is allocated through _cache_load().

For reference pasting end part of my code snipet for both
inetCidrRouteTable_container_load() and add_ipv6_route_entries()
respectively. As you can see, rowreq_ctx is passed to CONTAINER_INSERT and
i hope it's being freed properly. But Inside add_ipv6_route_entries(), we
are again allocating memory for "rowreq_ctx" and again passing it to
CONTAINER_INSERT in same way. So here which one i need to take care of ??
Whether I need to free the container or need to release memory by calling
inetCidrRouteTable_release_rowreq_ctx().?


----------------------------------------------------------------------
inetCidrRouteTable_container_load (netsnmp_container *container)
...
...
for (i = 0; i < route_table.no_entries; i++) {
...
...

CONTAINER_INSERT(container, rowreq_ctx);
++count;
}
status = add_ipv6_route_entries(container, &count);


DEBUGMSGT(("verbose:inetCidrRouteTable:inetCidrRouteTable_container_load",
"inserted %d records\n", (int) count));

return status;
} /* end of inetCidrRouteTable_container_load */
----------------------------------------------------------------------
add_ipv6_route_entries (netsnmp_container *container, size_t *count)
{
...
...
for (i = 0; i < route_table6.no_entries; i++) {
...
...
/*
* insert into table container
*/
CONTAINER_INSERT(container, rowreq_ctx);
++*count;
}
return MFD_SUCCESS;
} /* end of add_ipv6_route_entries */

----------------------------------------------------------------------

It would be great if someone can explain what is the use of container here
and how it is used to insert and delete/free . whether it is being
maintained in background everytime or only at the time of query.
For above case what could be done to get rid of this issue.
--
*Regards*,
Soubhagya
Peilong Xia
2016-11-08 03:21:28 UTC
Permalink
Hi Soubhagya,

Please see function netsnmp_access_route_container_free(), it’s called by
inetCidrRouteTable_container_load().



Peilong





*From:* Soubhagya Panigrahi [mailto:***@gmail.com]
*Sent:* 2016幎11月7日 21:56
*To:* net-snmp-***@lists.sourceforge.net;
net-snmp-***@lists.sourceforge.net
*Subject:* Memory leak in inetCidrRouteTable 5.7.3



Hi All,

I have some queries with respect to memory leak in inetCidrRouteTable while
continuous query to inetCidrRouteTable .

Valgrind report
===============

7480 ==16547== 7,569,856 bytes in 3,416 blocks are definitely lost in loss
record 5,344 of 5,344
7481 ==16547== at 0x4C266B0: calloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
7482 ==16547== by 0x475E04: inetCidrRouteTable_allocate_rowreq_ctx
(snmp/subagent/inetCidrRouteTable_interface.c:584)
7483 ==16547== by 0x47427A: add_ipv6_route_entries
(snmp/subagent/inetCidrRouteTable_data_access.c:792)
7484 ==16547== by 0x474856: inetCidrRouteTable_container_load
(snmp/subagent/inetCidrRouteTable_data_access.c:693)
7485 ==16547== by 0x52B83F4: _cache_load (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7486 ==16547== by 0x52B8F9C: netsnmp_cache_helper_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7487 ==16547== by 0x52CC2F6: netsnmp_call_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7488 ==16547== by 0x52C048C: table_helper_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7489 ==16547== by 0x52CD25E: netsnmp_call_handlers (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7490 ==16547== by 0x52D6880: handle_var_requests (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7491 ==16547== by 0x52D7ABF: handle_getnext_loop (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7492 ==16547== by 0x52DA8FF: netsnmp_handle_request (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7493 ==16547== by 0x52DB3D9: handle_snmp_packet (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7494 ==16547== by 0x574A217: ??? (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7495 ==16547== by 0x574ABF6: _sess_read (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7496 ==16547== by 0x574BA38: snmp_sess_read2 (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7497 ==16547== by 0x574BAFA: snmp_read2 (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7498 ==16547== by 0x574BB43: snmp_read (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7499 ==16547== by 0x430C7A: agent_check_and_process_mutex
(snmp/subagent/cwoAoStatsTable_subag

As part of my project, we have added a support for ipv6 route entry in
"add_ipv6_route_entries()" under inetCidrRouteTable_container_load().

Allocating memory is same, how it is being done in
"inetCidrRouteTable_container_load()". But as per valgrind report, Leak is
showing in newly implemented add_ipv6_route_entries() code not in
inetCidrRouteTable_container_load(). So it is obvious that memory
deallocation part is not being implemenetd properly.

here my question is where and how to free the newly allocated memory . The
reason why I am asking in this forum is whether to call release request or
need to check how can i use CONTAINER_FREE for this.

I could see, for inetCidrRouteTable_container_load, there is one respective
"inetCidrRouteTable_release_rowreq_ctx(rowreq_ctx)" to free the memory
called by _cache_free() which is allocated through _cache_load().

For reference pasting end part of my code snipet for both
inetCidrRouteTable_container_load() and add_ipv6_route_entries()
respectively. As you can see, rowreq_ctx is passed to CONTAINER_INSERT and
i hope it's being freed properly. But Inside add_ipv6_route_entries(), we
are again allocating memory for "rowreq_ctx" and again passing it to
CONTAINER_INSERT in same way. So here which one i need to take care of ??
Whether I need to free the container or need to release memory by calling
inetCidrRouteTable_release_rowreq_ctx().?


----------------------------------------------------------------------
inetCidrRouteTable_container_load (netsnmp_container *container)
...
...
for (i = 0; i < route_table.no_entries; i++) {
...
...

CONTAINER_INSERT(container, rowreq_ctx);
++count;
}
status = add_ipv6_route_entries(container, &count);


DEBUGMSGT(("verbose:inetCidrRouteTable:inetCidrRouteTable_container_load",
"inserted %d records\n", (int) count));

return status;
} /* end of inetCidrRouteTable_container_load */
----------------------------------------------------------------------
add_ipv6_route_entries (netsnmp_container *container, size_t *count)
{
...
...
for (i = 0; i < route_table6.no_entries; i++) {
...
...
/*
* insert into table container
*/
CONTAINER_INSERT(container, rowreq_ctx);
++*count;
}
return MFD_SUCCESS;
} /* end of add_ipv6_route_entries */

----------------------------------------------------------------------

It would be great if someone can explain what is the use of container here
and how it is used to insert and delete/free . whether it is being
maintained in background everytime or only at the time of query.
For above case what could be done to get rid of this issue.
--
*Regards*,
Soubhagya
Peilong Xia
2016-11-08 02:46:23 UTC
Permalink
Hi Soubhagya,

Please see function netsnmp_access_route_container_free(), it’s called by
inetCidrRouteTable_container_load().



Peilong



*From:* Soubhagya Panigrahi [mailto:***@gmail.com]
*Sent:* 2016幎11月7日 21:56
*To:* net-snmp-***@lists.sourceforge.net;
net-snmp-***@lists.sourceforge.net
*Subject:* Memory leak in inetCidrRouteTable 5.7.3



Hi All,

I have some queries with respect to memory leak in inetCidrRouteTable while
continuous query to inetCidrRouteTable .

Valgrind report
===============

7480 ==16547== 7,569,856 bytes in 3,416 blocks are definitely lost in loss
record 5,344 of 5,344
7481 ==16547== at 0x4C266B0: calloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
7482 ==16547== by 0x475E04: inetCidrRouteTable_allocate_rowreq_ctx
(snmp/subagent/inetCidrRouteTable_interface.c:584)
7483 ==16547== by 0x47427A: add_ipv6_route_entries
(snmp/subagent/inetCidrRouteTable_data_access.c:792)
7484 ==16547== by 0x474856: inetCidrRouteTable_container_load
(snmp/subagent/inetCidrRouteTable_data_access.c:693)
7485 ==16547== by 0x52B83F4: _cache_load (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7486 ==16547== by 0x52B8F9C: netsnmp_cache_helper_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7487 ==16547== by 0x52CC2F6: netsnmp_call_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7488 ==16547== by 0x52C048C: table_helper_handler (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7489 ==16547== by 0x52CD25E: netsnmp_call_handlers (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7490 ==16547== by 0x52D6880: handle_var_requests (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7491 ==16547== by 0x52D7ABF: handle_getnext_loop (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7492 ==16547== by 0x52DA8FF: netsnmp_handle_request (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7493 ==16547== by 0x52DB3D9: handle_snmp_packet (in
/sw/linuxapps/usr/lib64/libnetsnmpagent.so.30.0.3)
7494 ==16547== by 0x574A217: ??? (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7495 ==16547== by 0x574ABF6: _sess_read (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7496 ==16547== by 0x574BA38: snmp_sess_read2 (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7497 ==16547== by 0x574BAFA: snmp_read2 (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7498 ==16547== by 0x574BB43: snmp_read (in
/sw/linuxapps/usr/lib64/libnetsnmp.so.30.0.3)
7499 ==16547== by 0x430C7A: agent_check_and_process_mutex
(snmp/subagent/cwoAoStatsTable_subag

As part of my project, we have added a support for ipv6 route entry in
"add_ipv6_route_entries()" under inetCidrRouteTable_container_load().

Allocating memory is same, how it is being done in
"inetCidrRouteTable_container_load()". But as per valgrind report, Leak is
showing in newly implemented add_ipv6_route_entries() code not in
inetCidrRouteTable_container_load(). So it is obvious that memory
deallocation part is not being implemenetd properly.

here my question is where and how to free the newly allocated memory . The
reason why I am asking in this forum is whether to call release request or
need to check how can i use CONTAINER_FREE for this.

I could see, for inetCidrRouteTable_container_load, there is one respective
"inetCidrRouteTable_release_rowreq_ctx(rowreq_ctx)" to free the memory
called by _cache_free() which is allocated through _cache_load().

For reference pasting end part of my code snipet for both
inetCidrRouteTable_container_load() and add_ipv6_route_entries()
respectively. As you can see, rowreq_ctx is passed to CONTAINER_INSERT and
i hope it's being freed properly. But Inside add_ipv6_route_entries(), we
are again allocating memory for "rowreq_ctx" and again passing it to
CONTAINER_INSERT in same way. So here which one i need to take care of ??
Whether I need to free the container or need to release memory by calling
inetCidrRouteTable_release_rowreq_ctx().?


----------------------------------------------------------------------
inetCidrRouteTable_container_load (netsnmp_container *container)
...
...
for (i = 0; i < route_table.no_entries; i++) {
...
...

CONTAINER_INSERT(container, rowreq_ctx);
++count;
}
status = add_ipv6_route_entries(container, &count);


DEBUGMSGT(("verbose:inetCidrRouteTable:inetCidrRouteTable_container_load",
"inserted %d records\n", (int) count));

return status;
} /* end of inetCidrRouteTable_container_load */
----------------------------------------------------------------------
add_ipv6_route_entries (netsnmp_container *container, size_t *count)
{
...
...
for (i = 0; i < route_table6.no_entries; i++) {
...
...
/*
* insert into table container
*/
CONTAINER_INSERT(container, rowreq_ctx);
++*count;
}
return MFD_SUCCESS;
} /* end of add_ipv6_route_entries */

----------------------------------------------------------------------

It would be great if someone can explain what is the use of container here
and how it is used to insert and delete/free . whether it is being
maintained in background everytime or only at the time of query.
For above case what could be done to get rid of this issue.
--
*Regards*,
Soubhagya
Loading...