Re: Memory leaks found by DMALLOC?
Raphaël HUCK <[email protected]>
| Newsgroups | gmane.text.clearsilver.general |
|---|---|
| Message-ID | <[email protected]> |
> 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
>
>
>