Bart Van Assche wrote:
 > On Thu, Aug 6, 2009 at 12:02 PM,
 >> Any opinions of whether this error could be causing my glibc double free
 >> errors, or whether it is a red-herring?
 >
 > It is unlikely that the above message printed by Valgrind is related
 > to the double free reported by glibc.
 >
 > Try to trigger as much code as you can in your application and in
 > Net-SNMP and see whether this makes Valgrind report more errors.
 >
 > Bart.

Hi,

I left valgrind running for over 20 hours with the application doing 
some simple snmpget-ing. After 8.5 hours and 29,664 SNMP gets - I got 
the first valgrind errors - which were all from a single call to 
snmp_free_pdu with a pdu that had already been freed after a 
snmp_synch_response returned a STAT_ERROR. No other valgrind errors were 
received.

Normally the application would crash, but it seems valgrind allows it to 
continue - and the application ran for another 9 hours 22 minutes, and 
32,767 SNMP gets with no valgrind errors, and then I got the same 
valgrind errors complaining that the pdu had already been freed. The 
only valgrind errors I could find where as a direct result of memory 
being freed twice.

I have also noticed that if I do enough localhost snmpwalks - each 
around 3000 SNMP gets - I can reproduce the same problem. It seems after 
around 10 attempts on average, sometimes more, sometimes less. This may 
be just a fluke, or my imagination...

The problem seems to come down to the PDU being freed once when a 
STAT_ERROR is generated in snmp_synch_response_cb (snmp_client.c:1000):

  999     if ((state->reqid = snmp_send(ss, pdu)) == 0) {
1000         snmp_free_pdu(pdu);
1001         state->status = STAT_ERROR;
1002     } else
1003         state->waiting = 1;

And once again when snmp_close() is called as a result of this error. In 
snmp_sess_close() - the PDU that was freed above at snmp_client.c:1000 
is still on the input request list associated with the session at 
snmp_api.c:1886:

1847 /*
1848  * Close the input session.  Frees all data allocated for the session,
1849  * dequeues any pending requests, and closes any sockets allocated for
1850  * the session.  Returns 0 on error, 1 otherwise.
1851  */
1852 int
1853 snmp_sess_close(void *sessp)
1854 {
1855     struct session_list *slp = (struct session_list *) sessp;
1856     netsnmp_transport *transport;
1857     struct snmp_internal_session *isp;
1858     netsnmp_session *sesp = NULL;
1859     struct snmp_secmod_def *sptr;
1860
1861     if (slp == NULL) {
1862         return 0;
1863     }
1864
1865     if (slp->session != NULL &&
1866         (sptr = find_sec_mod(slp->session->securityModel)) != NULL &&
1867         sptr->session_close != NULL) {
1868         (*sptr->session_close) (slp->session);
1869     }
1870
1871     isp = slp->internal;
1872     slp->internal = 0;
1873
1874     if (isp) {
1875         netsnmp_request_list *rp, *orp;
1876
1877         SNMP_FREE(isp->packet);
1878
1879         /*
1880          * Free each element in the input request list.
1881         */
1882         rp = isp->requests;
1883         while (rp) {
1884             orp = rp;
1885             rp = rp->next_request;
1886             snmp_free_pdu(orp->pdu);
1887             free((char *) orp);
1888         }
1889
1890         free((char *) isp);
1891     }
...

The following is a dbg session for a standard snmpwalk - where you can 
see the pdu 0x9050960 was freed at snmp_client.c:1000 and was still on 
the request list at snmp_api.c:1885, and was freed again at 
snmp_api.c:1886, causing the double free.

Is this a bug, or a symptom of some other issue?

Any ideas, suggestions for other things to try would be much appreciated 
- as this problem is slowly driving me mad!

Many thanks,
Craig

# gdb /usr/local/bin/snmpwalk
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...
(gdb) set args -v2c -cpublic localhost
(gdb) b snmp_client.c:1000
No source file named snmp_client.c.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (snmp_client.c:1000) pending.
(gdb) run
Starting program: /usr/local/bin/snmpwalk -v2c -cpublic localhost
SNMPv2-MIB::sysDescr.0 = STRING: Linux *** 2.6.18-128.1.10.el5 #1 SMP 
Thu May 7 10:35:59 EDT 2009 x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (7619945) 21:09:59.45
SNMPv2-MIB::sysContact.0 = STRING: ***
SNMPv2-MIB::sysName.0 = STRING: ***
SNMPv2-MIB::sysLocation.0 = STRING: Unknown
...
...
...
IP-MIB::ipSystemStatsInUnknownProtos.ipv4 = Counter32: 0
IP-MIB::ipSystemStatsInForwDatagrams.ipv4 = Counter32: 0
IP-MIB::ipSystemStatsHCInForwDatagrams.ipv4 = Counter64: 0
IP-MIB::ipSystemStatsReasmReqds.ipv4 = Counter32: 0
IP-MIB::ipSystemStatsReasmOKs.ipv4 = Counter32: 0
IP-MIB::ipSystemStatsReasmFails.ipv4 = Counter32: 0
IP-MIB::ipSystemStatsInDiscards.ipv4 = Counter32: 0

Breakpoint 1, snmp_synch_response_cb (ss=0x8fffab0, pdu=0x9050960, 
response=0x7fff36a5a2d8, pcb=0x2b347407cf6c <snmp_synch_input>) at 
snmp_client.c:1000
1000            snmp_free_pdu(pdu);
(gdb) list
995         cbmagsav = ss->callback_magic;
996         ss->callback = pcb;
997         ss->callback_magic = (void *) state;
998
999         if ((state->reqid = snmp_send(ss, pdu)) == 0) {
1000            snmp_free_pdu(pdu);
1001            state->status = STAT_ERROR;
1002        } else
1003            state->waiting = 1;
1004
(gdb) print state->reqid
$1 = 0
(gdb) print pdu
$2 = (netsnmp_pdu *) 0x9050960
(gdb) print *pdu
$3 = {version = 1, command = 161, reqid = 0, msgid = 32703, transid = 0, 
sessid = 0, errstat = 0, errindex = 0, time = 0, flags = 512, 
securityModel = -1,
   securityLevel = 0, msgParseModel = 0, transport_data = 0x0, 
transport_data_length = 0, tDomain = 0x0, tDomainLen = 0, variables = 
0x9050a80,
   community = 0x9050320 "public", community_len = 6, enterprise = 0x0, 
enterprise_length = 0, trap_type = 0, specific_type = 0,
   agent_addr = "\000\000\000", contextEngineID = 0x0, 
contextEngineIDLen = 0, contextName = 0x0, contextNameLen = 0, 
securityEngineID = 0x0,
   securityEngineIDLen = 0, securityName = 0x0, securityNameLen = 0, 
priority = 0, range_subid = 0, securityStateRef = 0x0}
(gdb) n
1001            state->status = STAT_ERROR;
(gdb) print pdu
$4 = (netsnmp_pdu *) 0x9050960
(gdb) n
1005        while (state->waiting) {
(gdb) print state->waiting
$5 = 0
(gdb) s
1052        *response = state->pdu;
(gdb) bt
#0  snmp_synch_response_cb (ss=0x8fffab0, pdu=0x9050960, 
response=0x7fff36a5a2d8, pcb=0x2b347407cf6c <snmp_synch_input>) at 
snmp_client.c:1052
#1  0x00002b347407e4e9 in snmp_synch_response (ss=0x8fffab0, 
pdu=0x9050960, response=0x7fff36a5a2d8) at snmp_client.c:1062
#2  0x0000000000401360 in main (argc=<value optimized out>, argv=0x0) at 
snmpwalk.c:279
(gdb) s
1053        ss->callback = cbsav;
(gdb) s
1054        ss->callback_magic = cbmagsav;
(gdb) s
1055        return state->status;
(gdb) s
1056    }
(gdb) s
snmp_synch_response (ss=0x8fffab0, pdu=0x9050960, 
response=0x7fff36a5a2d8) at snmp_client.c:1063
1063    }
(gdb) s
main (argc=<value optimized out>, argv=0x0) at snmpwalk.c:280
280             if (status == STAT_SUCCESS) {
(gdb) s
279             status = snmp_synch_response(ss, pdu, &response);
(gdb) print status
$6 = 0
(gdb) s
280             if (status == STAT_SUCCESS) {
(gdb) n
350             } else if (status == STAT_TIMEOUT) {
(gdb) n
356                 snmp_sess_perror("snmpwalk", ss);
(gdb) n
snmpwalk:
360             if (response)
(gdb) s
269         while (running) {
(gdb) s
363         if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
(gdb) s
netsnmp_ds_get_boolean (storeid=1, which=4) at default_store.c:240
240         if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS ||
(gdb) s
245         return (netsnmp_ds_booleans[storeid][which/8] & (1 << (which 
% 8))) ? 1:0;
(gdb) s
246     }
(gdb) s
main (argc=<value optimized out>, argv=<value optimized out>) at 
snmpwalk.c:367
367         if (numprinted == 0 && status == STAT_SUCCESS) {
(gdb) s
377         snmp_close(ss);
(gdb) s
snmp_close (session=0x8fffab0) at snmp_api.c:1931
1931        struct session_list *slp = NULL, *oslp = NULL;
(gdb) list
1926    }
1927
1928    int
1929    snmp_close(netsnmp_session * session)
1930    {
1931        struct session_list *slp = NULL, *oslp = NULL;
1932
1933        {                           /*MTCRITICAL_RESOURCE */
1934            snmp_res_lock(MT_LIBRARY_ID, MT_LIB_SESSION);
1935            if (Sessions && Sessions->session == session) { /* If 
first entry */
(gdb) s
1935            if (Sessions && Sessions->session == session) { /* If 
first entry */
(gdb) s
1936                slp = Sessions;
(gdb) s
1937                Sessions = slp->next;
(gdb) s
1935            if (Sessions && Sessions->session == session) { /* If 
first entry */
(gdb) s
1950        if (slp == NULL) {
(gdb) s
1953        return snmp_sess_close((void *) slp);
(gdb) s
snmp_sess_close (sessp=0x90419a0) at snmp_api.c:1855
1855        struct session_list *slp = (struct session_list *) sessp;
(gdb) s
1858        netsnmp_session *sesp = NULL;
(gdb) s
1861        if (slp == NULL) {
(gdb) s
1865        if (slp->session != NULL &&
(gdb) s
find_sec_mod (secmod=3) at snmp_secmod.c:145
145         for (sptr = registered_services; sptr; sptr = sptr->next) {
(gdb) n
146             if (sptr->securityModel == secmod) {
(gdb) n
147                 return sptr->secDef;
(gdb) n
154     }
(gdb) n
snmp_sess_close (sessp=0x90419a0) at snmp_api.c:1871
1871        isp = slp->internal;
(gdb) s
1872        slp->internal = 0;
(gdb) s
1874        if (isp) {
(gdb) s
1877            SNMP_FREE(isp->packet);
(gdb) n
1882            rp = isp->requests;
(gdb) print isp->requests
$7 = (netsnmp_request_list *) 0x90503f0
(gdb) print *isp->requests
$8 = {next_request = 0x0, request_id = 0, message_id = 32703, callback = 
0, cb_data = 0x0, retries = 0, timeout = 1000000, time = {tv_sec = 
1250062211,
     tv_usec = 355904}, expire = {tv_sec = 1250062212, tv_usec = 
355904}, session = 0x0, pdu = 0x9050960}
(gdb) s
1883            while (rp) {
(gdb) s
1884                orp = rp;
(gdb) s
1885                rp = rp->next_request;
(gdb) print orp
$9 = (netsnmp_request_list *) 0x90503f0
(gdb) print *orp
$10 = {next_request = 0x0, request_id = 0, message_id = 32703, callback 
= 0, cb_data = 0x0, retries = 0, timeout = 1000000, time = {tv_sec = 
1250062211,
     tv_usec = 355904}, expire = {tv_sec = 1250062212, tv_usec = 
355904}, session = 0x0, pdu = 0x9050960}
(gdb) print orp->pdu
$11 = (netsnmp_pdu *) 0x9050960
(gdb) print *orp->pdu
$12 = {version = 0, command = 0, reqid = 0, msgid = 0, transid = 0, 
sessid = 0, errstat = 0, errindex = 0, time = 0, flags = 0, 
securityModel = 0,
   securityLevel = 0, msgParseModel = 0, transport_data = 0x0, 
transport_data_length = 0, tDomain = 0x0, tDomainLen = 0, variables = 
0x0, community = 0x0,
   community_len = 0, enterprise = 0x0, enterprise_length = 0, trap_type 
= 0, specific_type = 0, agent_addr = "\000\000\000", contextEngineID = 0x0,
   contextEngineIDLen = 0, contextName = 0x0, contextNameLen = 0, 
securityEngineID = 0x0, securityEngineIDLen = 0, securityName = 0x0, 
securityNameLen = 0,
   priority = 0, range_subid = 0, securityStateRef = 0x0}
(gdb) s
1886                snmp_free_pdu(orp->pdu);
(gdb) s
snmp_free_pdu (pdu=0x9050960) at snmp_api.c:5007
5007        if (!pdu)
(gdb) s
5030        if ((sptr = find_sec_mod(pdu->securityModel)) != NULL &&
(gdb) n
5034        snmp_free_varbind(pdu->variables);
(gdb) n
5035        SNMP_FREE(pdu->enterprise);
(gdb) n
5036        SNMP_FREE(pdu->community);
(gdb) n
5037        SNMP_FREE(pdu->contextEngineID);
(gdb) n
5038        SNMP_FREE(pdu->securityEngineID);
(gdb) n
5039        SNMP_FREE(pdu->contextName);
(gdb) n
5040        SNMP_FREE(pdu->securityName);
(gdb) n
5041        SNMP_FREE(pdu->transport_data);
(gdb) n
5042        memset(pdu, 0, sizeof(netsnmp_pdu));
(gdb) n
5043        free((char *) pdu);
(gdb) n
*** glibc detected *** /usr/local/bin/snmpwalk: double free or 
corruption (top): 0x0000000009050960 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3d0de71ce2]
/lib64/libc.so.6(cfree+0x8c)[0x3d0de7590c]
/usr/local/lib/libnetsnmp.so.15(snmp_free_pdu+0x1b8)[0x2b34740aae86]
/usr/local/lib/libnetsnmp.so.15(snmp_sess_close+0xeb)[0x2b347409eea0]
/usr/local/lib/libnetsnmp.so.15(snmp_close+0xc8)[0x2b347409f0e7]
/usr/local/bin/snmpwalk[0x4013f9]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x3d0de1d974]
/usr/local/bin/snmpwalk[0x400e19]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fd:00 14915774 
  /usr/local/bin/snmpwalk
00602000-00603000 rw-p 00002000 fd:00 14915774 
  /usr/local/bin/snmpwalk
08fcd000-09071000 rw-p 08fcd000 00:00 0 
  [heap]
3d0da00000-3d0da1c000 r-xp 00000000 fd:00 44236802 
  /lib64/ld-2.5.so
3d0dc1b000-3d0dc1c000 r--p 0001b000 fd:00 44236802 
  /lib64/ld-2.5.so
3d0dc1c000-3d0dc1d000 rw-p 0001c000 fd:00 44236802 
  /lib64/ld-2.5.so
3d0de00000-3d0df4c000 r-xp 00000000 fd:00 44236805 
  /lib64/libc-2.5.so
3d0df4c000-3d0e14c000 ---p 0014c000 fd:00 44236805 
  /lib64/libc-2.5.so
3d0e14c000-3d0e150000 r--p 0014c000 fd:00 44236805 
  /lib64/libc-2.5.so
3d0e150000-3d0e151000 rw-p 00150000 fd:00 44236805 
  /lib64/libc-2.5.so
3d0e151000-3d0e156000 rw-p 3d0e151000 00:00 0
3d0e200000-3d0e202000 r-xp 00000000 fd:00 44236812 
  /lib64/libdl-2.5.so
3d0e202000-3d0e402000 ---p 00002000 fd:00 44236812 
  /lib64/libdl-2.5.so
3d0e402000-3d0e403000 r--p 00002000 fd:00 44236812 
  /lib64/libdl-2.5.so
3d0e403000-3d0e404000 rw-p 00003000 fd:00 44236812 
  /lib64/libdl-2.5.so
3d0ee00000-3d0ee14000 r-xp 00000000 fd:00 14916464 
  /usr/lib64/libz.so.1.2.3
3d0ee14000-3d0f013000 ---p 00014000 fd:00 14916464 
  /usr/lib64/libz.so.1.2.3
3d0f013000-3d0f014000 rw-p 00013000 fd:00 14916464 
  /usr/lib64/libz.so.1.2.3
3d0fe00000-3d0fe0d000 r-xp 00000000 fd:00 44236827 
  /lib64/libgcc_s-4.1.2-20080825.so.1
3d0fe0d000-3d1000d000 ---p 0000d000 fd:00 44236827 
  /lib64/libgcc_s-4.1.2-20080825.so.1
3d1000d000-3d1000e000 rw-p 0000d000 fd:00 44236827 
  /lib64/libgcc_s-4.1.2-20080825.so.1
3d15600000-3d1572d000 r-xp 00000000 fd:00 44236859 
  /lib64/libcrypto.so.0.9.8e
3d1572d000-3d1592c000 ---p 0012d000 fd:00 44236859 
  /lib64/libcrypto.so.0.9.8e
3d1592c000-3d1594d000 rw-p 0012c000 fd:00 44236859 
  /lib64/libcrypto.so.0.9.8e
3d1594d000-3d15951000 rw-p 3d1594d000 00:00 0
2b347404d000-2b347404e000 rw-p 2b347404d000 00:00 0
2b3474066000-2b3474067000 rw-p 2b3474066000 00:00 0
2b3474067000-2b347410d000 r-xp 00000000 fd:00 14915178 
  /usr/local/lib/libnetsnmp.so.15.1.2
2b347410d000-2b347430d000 ---p 000a6000 fd:00 14915178 
  /usr/local/lib/libnetsnmp.so.15.1.2
2b347430d000-2b3474311000 rw-p 000a6000 fd:00 14915178 
  /usr/local/lib/libnetsnmp.so.15.1.2
2b3474311000-2b3474348000 rw-p 2b3474311000 00:00 0
2b3474348000-2b3477916000 r--p 00000000 fd:00 14929693 
  /usr/lib/locale/locale-archive
2b3477916000-2b3477917000 rw-p 2b3477916000 00:00 0
2b347792e000-2b3477938000 r-xp 00000000 fd:00 44237085 
  /lib64/libnss_files-2.5.so
2b3477938000-2b3477b37000 ---p 0000a000 fd:00 44237085 
  /lib64/libnss_files-2.5.so
2b3477b37000-2b3477b38000 r--p 00009000 fd:00 44237085 
  /lib64/libnss_files-2.5.so
2b3477b38000-2b3477b39000 rw-p 0000a000 fd:00 44237085 
  /lib64/libnss_files-2.5.so
2b3478000000-2b3478021000 rw-p 2b3478000000 00:00 0
2b3478021000-2b347c000000 ---p 2b3478021000 00:00 0
7fff36a47000-7fff36a5c000 rw-p 7ffffffea000 00:00 0 
  [stack]
ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0
Program received signal SIGABRT, Aborted.
0x0000003d0de30215 in raise () from /lib64/libc.so.6
(gdb)






__________ Information from ESET Smart Security, version of virus signature 
database 4328 (20090812) __________

The message was checked by ESET Smart Security.

http://www.eset.com



------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to