[Pkg-net-snmp-devel] Bug#510495: memory profiler results

Dave Johnson dave-debian-01 at centerclick.org
Sun Jan 18 19:03:32 UTC 2009


John Morrissey writes:
> The next step would probably involve running snmpd in debug mode and
> comparing the output to what's being done in the source. Poking at the
> functions in these backtraces with gdb(1) might be more productive.

something in ipAddressTable_cache_load() or more specifically
_check_entry_for_updates() looks like a problem.

with 100 vlans, and 103 total interfaces:

here's the progression in ipAddressTable_cache_load() 


before _check_entry_for_updates iteration:

(gdb) call container->get_size(container)
$89 = 104
(gdb) call ipaddress_container->get_size(ipaddress_container)
$90 = 204

after _check_entry_for_updates iteration:

(gdb) call container->get_size(container)
$93 = 104
(gdb) call ipaddress_container->get_size(ipaddress_container)
$94 = 100

after _add_new_entry iteration:

(gdb) call container->get_size(container)
$96 = 104
(gdb) call ipaddress_container->get_size(ipaddress_container)
$97 = 100

the next call after the _add_new_entry is to free
ipaddress_container.  the comment seems incorrect as there are still
100 entries in ipaddress_container.

    /*
     * free the container. we've either claimed each entry, or released it,
     * so the access function doesn't need to clear the container.
     */
    netsnmp_access_ipaddress_container_free(ipaddress_container,
                                            NETSNMP_ACCESS_IPADDRESS_FREE_DONT_CLEAR);


Back at the beginning we see the 204 entries:


(gdb) p *(binary_array_table*)ipaddress_container->container_data
$107 = {max_size = 320, count = 204, flags = 0, dirty = 1, data_size = 4, data = 0x8310638}

(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[0]
$111 = {oid_index = {len = 0x1, oids = 0x812fc30}, ns_ia_index = 0x1, flags = 0x0, ia_address = {0x7f, 0x0, 0x0, 0x1, 0x0 <repeats 12 times>}, if_index = 0x1, ia_prefix_oid = 0x0, ia_address_len = 0x4, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x2, ia_storagetype = 0x2, arch_data = 0x8149b00}
(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[1]
$112 = {oid_index = {len = 0x1, oids = 0x811d948}, ns_ia_index = 0x2, flags = 0x0, ia_address = {0xa, 0xc8, 0xca, 0xec, 0x0 <repeats 12 times>}, if_index = 0x2, ia_prefix_oid = 0x0, ia_address_len = 0x4, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x2, ia_storagetype = 0x2, arch_data = 0x8264438}

(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[2]
$113 = {oid_index = {len = 0x1, oids = 0x8130950}, ns_ia_index = 0x3, flags = 0x0, ia_address = {0xa, 0x2, 0x64, 0x1, 0x0 <repeats 12 times>}, if_index = 0x3, ia_prefix_oid = 0x0, ia_address_len = 0x4, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x2, ia_storagetype = 0x2, arch_data = 0x812a660}
(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[3]
$114 = {oid_index = {len = 0x1, oids = 0x8136148}, ns_ia_index = 0x4, flags = 0x0, ia_address = {0xa, 0x2, 0x65, 0x1, 0x0 <repeats 12 times>}, if_index = 0x4, ia_prefix_oid = 0x0, ia_address_len = 0x4, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x2, ia_storagetype = 0x2, arch_data = 0x812a418}
(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[4]
$115 = {oid_index = {len = 0x1, oids = 0x812fa20}, ns_ia_index = 0x5, flags = 0x0, ia_address = {0xa, 0x2, 0x66, 0x1, 0x0 <repeats 12 times>}, if_index = 0x5, ia_prefix_oid = 0x0, ia_address_len = 0x4, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x2, ia_storagetype = 0x2, arch_data = 0x8131da0}

(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[102]
$122 = {oid_index = {len = 0x1, oids = 0x8166610}, ns_ia_index = 0x67, flags = 0x0, ia_address = {0x0 <repeats 15 times>, 0x1}, if_index = 0x1, ia_prefix_oid = 0x0, ia_address_len = 0x10, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x2, ia_storagetype = 0x2, arch_data = 0x8166658}
(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[103]
$123 = {oid_index = {len = 0x1, oids = 0x8166690}, ns_ia_index = 0x68, flags = 0x0, ia_address = {0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x54, 0x0, 0xff, 0xfe, 0x66, 0x0, 0x97}, if_index = 0x66, ia_prefix_oid = 0x0, ia_address_len = 0x10, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x5, ia_storagetype = 0x2, arch_data = 0x81666d8}
(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[104]
$124 = {oid_index = {len = 0x1, oids = 0x82fd680}, ns_ia_index = 0x69, flags = 0x0, ia_address = {0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x54, 0x0, 0xff, 0xfe, 0x66, 0x0, 0x97}, if_index = 0x65, ia_prefix_oid = 0x0, ia_address_len = 0x10, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x5, ia_storagetype = 0x2, arch_data = 0x82fd6c8}
(gdb) p /x *(netsnmp_ipaddress_entry*)((binary_array_table*)ipaddress_container->container_data)->data[105]
$125 = {oid_index = {len = 0x1, oids = 0x82fd700}, ns_ia_index = 0x6a, flags = 0x0, ia_address = {0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x54, 0x0, 0xff, 0xfe, 0x66, 0x0, 0x97}, if_index = 0x64, ia_prefix_oid = 0x0, ia_address_len = 0x10, ia_prefix_oid_len = 0x0, ia_type = 0x1, ia_status = 0x1, ia_origin = 0x5, ia_storagetype = 0x2, arch_data = 0x82fd748}

are:

lo ipv4
eth0 ipv4
[the 100 vlans ipv4]
[lo ipv6]
[the 100 vlan ipv6 link local]

missing is the ipv6 link local of eth0

It's unclear if ipAddressTable_cache_load is meant to handle IPv6
addresses and if so, there is clearly brokenness for duplicate IPv6
link local addresses (which will of course exist when VLANs are
present)

_check_entry_for_updates() only does a binary search for the first
matching ipv4/ipv6 address, ignoring the fact duplicate ip addresses
appear to be present in the list.  Again, unclear if these duplicates
should be in the list or not.  someone more familiar with this code
would have to comment.

-- 
Dave





More information about the Pkg-net-snmp-devel mailing list