Yahoo Groups archive

Milter-greylist

Index last updated: 2026-04-28 23:32 UTC

Message

Re: [milter-greylist] memory consumption

2010-02-18 by Dietmar Rieder

On 02/18/2010 11:40 AM, manu@... wrote:
>
>
> Dietmar Rieder <adrieder@...
> <mailto:adrieder%40sbox.tugraz.at>> wrote:
>
>  > libumem.so.1`malloc+0x23
>  > libresolv.so.2`__res_vinit+0x118
>  > libresolv.so.2`res_ninit+0x1a
>  > dnsrbl_check_source+0x14a
>
> A quick look at NetBSD's res_ninit() sources (it's from BIND, and I
> beleive most system have the same), indeed shows a malloc():
> statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext));
>
> This means that any successful call to res_ninit() must have a
> corresponding res_ndestroy() call.
>
> In dnsrbl_check_source, once res_ninit() is called, there is no way out
> of the function without executing res_ndestroy(). But the trick is that
> res_ninit() and res_ndestroy() may be macros in milter-greylist, so that
> we can cope with older BIND resolvers without having #ifdef's everywhere
> in our code.
>
> In some situation, milter-greylist can define res_ndestroy() as
> res_nclose(), and this is a problem, because at least in NetBSD's
> resolver, res_ndestroy() does free statp->_u._ext.ext whereas
> res_nclose() does not.
>
> Hence, here is the offending code in dnsrbl.c
>
> #if (defined(res_ninit) || (__RES >= 19991006) )
> #define HAVE_RESN 1
> #ifndef res_ndestroy
> #define res_ndestroy(res) res_nclose(res) /* <--- XXXhereXXX */
> #endif
> #else
> #define res_ninit(res) \
> ((_res.options & RES_INIT) == 0 && res_init())
> #define res_nquery(res, req, class, type, ans, anslen) \
> res_query(req, class, type, ans, anslen)
> #define res_ndestroy(res)
> #endif
>
> The ifdef on res_ninit and res_ndestroy is an error, it will never be
> evaluated as true. Please try this instead, and tell us if you get the
> warning at compile time.
>
> #if (__RES >= 19991006) )
> #define HAVE_RESN 1
> #else
> #warn "no res_ninit!"
> #define res_ninit(res) \
> ((_res.options & RES_INIT) == 0 && res_init())
> #define res_nquery(res, req, class, type, ans, anslen) \
> res_query(req, class, type, ans, anslen)
> #define res_ndestroy(res)
> #endif
>
> Handling the BIND versions where res_nclose() exists but not
> res_ndestroy() must be done by an autoconf test.


Hi thanks for the quick response and analysis. I changed the dnsrbl.c 
file as indicated and recompiled the milter. I didn't get a warning at 
compile time.

I genereated a core dump after some minute, and now it looks really 
promising!!!!

gcore 6891
mdb core.6891
 > ::findleaks -dvf
findleaks:                maximum buffers => 873580
findleaks:                 actual buffers => 872852
findleaks:
findleaks:             potential pointers => 8311361
findleaks:                     dismissals => 2091319       (25.1%)
findleaks:                         misses => 4770578       (57.3%)
findleaks:                           dups => 576612        ( 6.9%)
findleaks:                        follows => 872852        (10.5%)
findleaks:
findleaks:              elapsed wall time => 5 seconds
findleaks:
CACHE     LEAKED   BUFCTL CALLER
----------------------------------------------------------------------
    Total       0 buffers, 0 bytes

I'll observe it for a while and I'll let you know if there is any 
leaking left.

THANK you so much!

Didi

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.