Hi all,

In an application I am using memory home pools allocated from heap. I
create home objects using su_home_new() and destroy them with
su_home_unref().

In some situations, I have noticed memory leaks indicating that the
memory allocated for the home object was lost, while su_home_unref()
reported the pool as freed, ie return value was 1.

After a bit of digging, I have found that a call to su_home_move()
marks the destination home as allocated on stack (ie
suh_blocks->sub_hauto is set to 1) if home's block hash table has to
be resized, or actually re-allocated, to accommodate moved
allocations.

Please find below:
 - the test case to reproduce the leak,
 - Valgrind report for test case run on a i686 host,
 - patch against 1.12.11 with a proposed fix.

Cheers,
Jakub Sitnicki

-- 
Azetti Networks
www.azetti.com

#include <assert.h>
#include <sofia-sip/su_alloc.h>

#define SUB_N 31                /* defined in su_alloc.c */

int main(int argc, char *argv[])
{
    struct my_home {
        su_home_t home[1];
    };

    struct my_home *h1;
    struct my_home *h2;
    int i;

    h1 = su_home_new( sizeof(struct my_home) );
    h2 = su_home_new( sizeof(struct my_home) );
    assert( h1 );
    assert( h2 );

    /* make enough allocs to cause su_home_move to re-alloc
     * suh_blocks, that is > 2 * SUB_N / 3, where SUB_N = 31 */
    for (i = 0; i < 2 * SUB_N / 3 + 1; i++)
        assert( su_alloc(h2->home, 1) );

    assert( su_home_move(h1->home, h2->home) == 0 );
    /* h1->home->suh_blocks->sub_hauto is now 1 */

    assert( su_home_unref(h2->home) );
    assert( su_home_unref(h1->home) );
    /* memory leak, h1 not freed */

    return 0;
}

$ valgrind --leak-check=full ./a.out
==16355== Memcheck, a memory error detector
==16355== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==16355== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==16355== Command: ./a.out
==16355== 
==16355== 
==16355== HEAP SUMMARY:
==16355==     in use at exit: 12 bytes in 1 blocks
==16355==   total heap usage: 28 allocs, 27 frees, 2,137 bytes allocated
==16355== 
==16355== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==16355==    at 0x400522F: calloc (vg_replace_malloc.c:418)
==16355==    by 0x76C072: su_home_new (su_alloc.c:559)
==16355==    by 0x8048588: main (bug-su-home-move.c:16)
==16355== 
==16355== LEAK SUMMARY:
==16355==    definitely lost: 12 bytes in 1 blocks
==16355==    indirectly lost: 0 bytes in 0 blocks
==16355==      possibly lost: 0 bytes in 0 blocks
==16355==    still reachable: 0 bytes in 0 blocks
==16355==         suppressed: 0 bytes in 0 blocks
==16355== 
==16355== For counts of detected and suppressed errors, rerun with: -v
==16355== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 28 from 8)

diff -upr sofia-sip-1.12.11.orig/libsofia-sip-ua/su/su_alloc.c 
sofia-sip-1.12.11/libsofia-sip-ua/su/su_alloc.c
--- sofia-sip-1.12.11.orig/libsofia-sip-ua/su/su_alloc.c        2011-03-11 
15:49:19.000000000 +0100
+++ sofia-sip-1.12.11/libsofia-sip-ua/su/su_alloc.c     2011-05-02 
17:16:32.174648988 +0200
@@ -1130,7 +1130,10 @@ int su_home_move(su_home_t *dst, su_home
          d2->sub_preload = d->sub_preload;
          d2->sub_prsize = d->sub_prsize;
          d2->sub_prused = d->sub_prused;
+         d2->sub_hauto = d->sub_hauto;
          d2->sub_preauto = d->sub_preauto;
+         d2->sub_destructor = d->sub_destructor;
+         /* auto & auto_all are not copied! */
          d2->sub_stats = d->sub_stats;
        }

------------------------------------------------------------------------------
WhatsUp Gold - Download Free Network Management Software
The most intuitive, comprehensive, and cost-effective network 
management toolset available today.  Delivers lowest initial 
acquisition cost and overall TCO of any competing solution.
http://p.sf.net/sfu/whatsupgold-sd
_______________________________________________
Sofia-sip-devel mailing list
Sofia-sip-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel

Reply via email to