Search the web
Sign In
New User? Sign Up
ClearSilver
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Want to share photos of your group with the world? Add a group photo to Flickr.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
Memory leaks found by DMALLOC?   Message List  
Reply | Forward Message #1231 of 1347 |
Re: Memory leaks found by DMALLOC?

As it turns out, this was found (and fixed) by an engineer here a couple
months back, I just didn't remember it. I really need to get a new
relase out. Our fix is to correctly pass on the error from
cgiwrap_writevf with nerr_pass in cgiwrap_writef.

I hadn't noticed that all the calls to cgiwrap_writef don't check the
return code, so I'll have to fix that.

I really need to get a release out, I've been waiting on a few things
people have been working on before doing it, so I'll push on them.

Brandon

On 10/27/08 raphael.huck uttered the following other thing:
> I've found the problem a long time ago, and forgot to post it.
>
> I just stumbled on my old message, so I figured I'd post a followup :)
>
> In fact the problem comes from cgiwrap_writef in cgi/cgiwrap.c:
>
> NEOERR *cgiwrap_writef (const char *fmt, ...)
> {
> va_list ap;
>
> va_start (ap, fmt);
> cgiwrap_writevf (fmt, ap);
> va_end (ap);
> return STATUS_OK;
> }
>
> cgiwrap_writevf returns a NEOERR * which isn't checked in
> cgiwrap_writef. If cgiwrap_writevf returns STATUS_OK, everything is
> fine, if not, the allocated structure is never freed. That is the
> memory leak I was talking about in my previous mail.
>
> If we have a look at the code of cgiwrap_writevf, we can see:
>
> r = GlobalWrapper.writef_cb (GlobalWrapper.data, fmt, ap);
> if (r)
> return nerr_raise_errno (NERR_IO, "writef_cb returned %d", r);
>
> Thus, if the writef callback you have given to cgiwrap_init_emu
> doesn't return 0, an error structure will be allocated and returned,
> but never handled.
>
> The quick solution is to simply have the writef callback always return
> 0: cgiwrap_writevf will then never allocate an error structure, so no
> memory leak.
>
> So instead of doing this (which triggers the memory leak):
>
> int writef_cb(void *ptr, const char *format, va_list ap)
> {
> UNUSED(ptr);
>
> return FCGI_vprintf(format, ap);
> }
>
> do this:
>
> int writef_cb(void *ptr, const char *format, va_list ap)
> {
> UNUSED(ptr);
>
> FCGI_vprintf(format, ap);
>
> return 0;
> }
>
>
> The cleaner solution would be to modify cgiwrap_writef in order to
> handle the error returned by cgiwrap_writevf.
>
> But then each call to cgiwrap_writef should have to check the return
> value, and deal with the potential error structure, or there would be
> even more memory leaks.
>
> In cgi/cgi.c there are several calls to cgiwrap_writef which don't
> check the return value...
>
> So I don't know if the clean solution is a good idea.
>
> What do you think Brandon?
>
> Thanks in advance for your advice.
>
> --Raphaël
>
> >
> > > I'll try to find more information about the leaked memory.
> > >
> > > I forgot to mention that when I comment out the following lines:
> > >
> > > err = cgi_display(cgi, "test.cst");
> > > nerr_ignore(&err);
> > >
> > > there are no longer memory leaks, so it seems to come from
> cgi_display.
> >
> > I've found more information.
> >
> > I'm using the following wrappers for FastCGI:
> >
> > /* FCGI_fread wrapper for ClearSilver CGI */
> > int read_cb(void *ptr, char *data, int size)
> > {
> > UNUSED(ptr);
> >
> > return FCGI_fread(data, sizeof(char), size, FCGI_stdin);
> > }
> >
> > /* FCGI_vprintf wrapper for ClearSilver CGI */
> > int writef_cb(void *ptr, const char *format, va_list ap)
> > {
> > UNUSED(ptr);
> >
> > return FCGI_vprintf(format, ap);
> > }
> >
> > /* FCGI_fwrite wrapper for ClearSilver CGI */
> > int write_cb(void *ptr, const char *data, int size)
> > {
> > UNUSED(ptr);
> >
> > return FCGI_fwrite((void *) data, sizeof(char), size, FCGI_stdout);
> > }
> >
> > and then I call:
> >
> > cgiwrap_init_emu(NULL, &read_cb, &writef_cb, &write_cb, NULL, NULL,
> NULL);
> >
> > The error I get is:
> >
> > in cgiwrap.c:0192:cgiwrap_writevf - writef_cb returned 27: [134]
> > Transport endpoint is not connected
> >
> >
> > Then I had a look at cgi/fcgi_hello.c and saw this line (by the way, I
> > think 'environ' should be replaced by 'envp' in this line):
> >
> > cgiwrap_init_std(argc, argv, environ);
> >
> > and added this line to my code before the call to cgiwrap_init_emu, but
> > I still have the same error.
> >
> > Then I've tried using the following from cgi/fcgi_hello.c instead:
> >
> > int cs_printf(void *ctx, const char *s, va_list args)
> > {
> > UNUSED(ctx);
> >
> > return printf(s, args);
> > }
> >
> > int cs_write(void *ctx, const char *s, int n)
> > {
> > UNUSED(ctx);
> >
> > return fwrite(s, n, 1, FCGI_stdout);
> > }
> >
> > and calling this:
> >
> > cgiwrap_init_emu(NULL, NULL, cs_printf, cs_write, NULL, NULL, NULL);
> >
> > but it makes things worse as this gives me 2 errors then:
> >
> > in cgiwrap.c:0192:cgiwrap_writevf - writef_cb returned 27: [134]
> > Transport endpoint is not connected
> >
> > in cgiwrap.c:0210:cgiwrap_write - write_cb returned 1<2488: [134]
> > Transport endpoint is not connected
> >
> >
> > --Raphael
> >
> > >> On 08/02/07 Raphaël HUCK uttered the following other thing:
> > >>> I've made a simple example to try and understand where these
> leaks come
> > >>> from:
> > >>>
> > >>> void fcgi_begin(void)
> > >>> {
> > >>> NEOERR *err;
> > >>>
> > >>> err = cgi_init(&cgi, NULL);
> > >>> nerr_ignore(&err);
> > >>> }
> > >>>
> > >>> void fcgi_end(void)
> > >>> {
> > >>> cgi_destroy(&cgi);
> > >>> }
> > >>>
> > >>> void fcgi_dispatch(void)
> > >>> {
> > >>> NEOERR *err;
> > >>>
> > >>> err = hdf_read_file(cgi->hdf, "test.hdf");
> > >>> nerr_ignore(&err);
> > >>>
> > >>> err = cgi_display(cgi, "test.cst");
> > >>> nerr_ignore(&err);
> > >>>
> > >>> return;
> > >>> }
> > >>>
> > >>> int main(int argc, char **argv)
> > >>> {
> > >>> UNUSED(argc);
> > >>> UNUSED(argv);
> > >>>
> > >>> while (FCGI_Accept() >= 0)
> > >>> {
> > >>> #ifdef DMALLOC
> > >>> unsigned long mark;
> > >>> /* get the current dmalloc position */
> > >>> mark = dmalloc_mark();
> > >>> #endif
> > >>>
> > >>> fcgi_begin();
> > >>> fcgi_dispatch();
> > >>> fcgi_end();
> > >>>
> > >>> #ifdef DMALLOC
> > >>> /*
> > >>> * log unfreed pointers that have been added to
> > >>> * the heap since mark
> > >>> */
> > >>> dmalloc_log_changed(mark,
> > >>> 1 /* log unfreed pointers */,
> > >>> 0 /* do not log freed pointers */,
> > >>> 1 /* log each pnt otherwise summary */);
> > >>> #endif
> > >>> }
> > >>>
> > >>> return 0;
> > >>> }
> > >>>
> > >>> And I get the following results with dmalloc:
> > >>>
> > >>> $ dmalloc_summarize.pl fastcgi < fastcgi.3393
> > >>> size count gross function
> > >>> 37 10036 total
> > >>> 284 35 9940 ra=0x419748
> > >>> 80 1 80 _err_alloc+64> and ends at
> 0x41974c
> > >>> <_err_alloc [neo_err.c:59]
> > >>> 16 1 16 check_resize+76> and ends at
> 0x41b8d8
> > >>> <check_resize [ulist.c:37]
> > >>>
> > >>>
> > >>>
> > >>> --Raphael
> > >>>
> > >>>> Anything that returns a NEOERR is allocating memory on error.
> You must
> > >>>> check the return value and call one of the methods to free the
> data,
> > >>>> usually one of:
> > >>>>
> > >>>> nerr_log_error
> > >>>> nerr_ignore
> > >>>> nerr_handle
> > >>>>
> > >>>> See util/neo_err.h for details.
> > >>>>
> > >>>> The uListInit one is probably from nerr_init, which allocates a
> very
> > >>>> small amount of memory once.
> > >>>>
> > >>>> Brandon
> > >>>>
> > >>>> On 07/31/07 raphael.huck uttered the following other thing:
> > >>>>> Hi,
> > >>>>>
> > >>>>> Here's what I've found with DMALLOC:
> > >>>>>
> > >>>>> $ dmalloc_summarize.pl fastcgi < fastcgi.10983
> > >>>>> size count gross function
> > >>>>> 1494 401044 total
> > >>>>> 284 1364 387376 ra=0x436818
> > >>>>> 1176 9 10584 _err_alloc+64> and ends at
> 0x43681c
> > >>>>> <_err_alloc [neo_err.c:59]
> > >>>>> 240 2 480 hcreate_r
> > >>>>> 16 4 64 check_resize+76> and ends at
> > >>>>> 0x4389a8 <check_resize [ulist.c:37]
> > >>>>> 20 3 60 uListInit+68> and ends at
> 0x438a5c
> > >>>>> <uListInit [ulist.c:61]
> > >>>>>
> > >>>>>
> > >>>>>
> > >>>>> The part which leaks the most memory is around 0x436818, which is:
> > >>>>>
> > >>>>> $ mips-linux-objdump -S fastcgi | grep -A 21 -B 25 436818
> > >>>>> static NEOERR *_err_alloc(void)
> > >>>>> {
> > >>>>> 4367d0: 3c1c0fbd lui gp,0xfbd
> > >>>>> 4367d4: 279c2c10 addiu gp,gp,11280
> > >>>>> 4367d8: 0399e021 addu gp,gp,t9
> > >>>>> 4367dc: 27bdffe0 addiu sp,sp,-32
> > >>>>> 4367e0: afbf0018 sw ra,24(sp)
> > >>>>> 4367e4: afbc0010 sw gp,16(sp)
> > >>>>> NEOERR *err;
> > >>>>>
> > >>>>> if (!UseFreeList || FreeList == NULL)
> > >>>>> 4367e8: 8f828018 lw v0,-32744(gp)
> > >>>>> 4367ec: 8f878018 lw a3,-32744(gp)
> > >>>>> {
> > >>>>> err = (NEOERR *)calloc (1, sizeof (NEOERR));
> > >>>>> 4367f0: 8f9988dc lw t9,-30500(gp)
> > >>>>> 4367f4: 8c4325d0 lw v1,9680(v0)
> > >>>>> 4367f8: 2405011c li a1,284
> > >>>>> 4367fc: 10600004 beqz v1,436810 <_err_alloc+0x40>
> > >>>>> 436800: 24040001 li a0,1
> > >>>>> 436804: 8ce625cc lw a2,9676(a3)
> > >>>>> 436808: 14c0000d bnez a2,436840 <_err_alloc+0x70>
> > >>>>> 43680c: 8fbf0018 lw ra,24(sp)
> > >>>>> 436810: 0320f809 jalr t9
> > >>>>> 436814: 00000000 nop
> > >>>>> 436818: 8fbc0010 lw gp,16(sp)
> > >>>>> if (err == NULL)
> > >>>>> {
> > >>>>> ne_warn ("INTERNAL ERROR: Unable to allocate memory for
> > >>>>> NEOERR");
> > >>>>> return INTERNAL_ERR;
> > >>>>> }
> > >>>>> return err;
> > >>>>> 43681c: 00402821 move a1,v0
> > >>>>> 436820: 8f848024 lw a0,-32732(gp)
> > >>>>> 436824: 8f998aa4 lw t9,-30044(gp)
> > >>>>> 436828: 1040000f beqz v0,436868 <_err_alloc+0x98>
> > >>>>> 43682c: 24844130 addiu a0,a0,16688
> > >>>>> }
> > >>>>> else
> > >>>>> {
> > >>>>> err = FreeList;
> > >>>>> FreeList = FreeList->next;
> > >>>>> }
> > >>>>> err->flags |= NE_IN_USE;
> > >>>>> err->next = NULL;
> > >>>>> return err;
> > >>>>> }
> > >>>>>
> > >>>>> These seem to be memory leaks. Can anyone confirm?
> > >>>>>
> > >>>>> --Raphaël HUCK
> > >>>>>
> > >>>>>
> > >>>>>
> > >>>>>
> > >>>>> Yahoo! Groups Links
> > >>>>>
> > >>>>>
> > >>>>>
> > >
> > >
> > >
> > >
> > > Yahoo! Groups Links
> > >
> > >
> > >
> >
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
--
"The only thing nude playing cards are good for is playing solitaire."
-- Harry Anderson, PI 1/7/98
http://www.fiction.net/blong/



Thu Nov 20, 2008 7:37 am

blong42
Offline Offline
Send Email Send Email

Forward
Message #1231 of 1347 |
Expand Messages Author Sort by Date

Hi, Here's what I've found with DMALLOC: $ dmalloc_summarize.pl fastcgi < fastcgi.10983 size count gross function 1494 401044 total 284...
raphael.huck
Offline Send Email
Jul 31, 2007
2:17 pm

Anything that returns a NEOERR is allocating memory on error. You must check the return value and call one of the methods to free the data, usually one of: ...
Brandon Long
blong42
Offline Send Email
Jul 31, 2007
9:05 pm

I've made a simple example to try and understand where these leaks come from: void fcgi_begin(void) { NEOERR *err; err = cgi_init(&cgi, NULL); ...
Raphaël HUCK
raphael.huck
Offline Send Email
Aug 2, 2007
1:48 pm

Is this the latest version? Much older versions used to use a FreeList for NEOERR's instead of always allocating new ones... but that still seems odd. Hmm,...
Brandon Long
blong42
Offline Send Email
Aug 2, 2007
11:14 pm

... Yes, I'm using the latest version (0.10.5). At the beginning of neo_err.c, there is this line: static int UseFreeList = 0; So I guess the FreeList is not...
Raphaël HUCK
raphael.huck
Offline Send Email
Aug 3, 2007
8:23 am

... I've found more information. I'm using the following wrappers for FastCGI: /* FCGI_fread wrapper for ClearSilver CGI */ int read_cb(void *ptr, char *data,...
Raphaël HUCK
raphael.huck
Offline Send Email
Aug 3, 2007
9:48 am

I've found the problem a long time ago, and forgot to post it. I just stumbled on my old message, so I figured I'd post a followup :) In fact the problem comes...
raphael.huck
Offline Send Email
Oct 27, 2008
5:25 pm

As it turns out, this was found (and fixed) by an engineer here a couple months back, I just didn't remember it. I really need to get a new relase out. Our...
Brandon Long
blong42
Offline Send Email
Nov 20, 2008
7:37 am
Advanced

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help