ramkrishanbhatt / modwsgi

Automatically exported from code.google.com/p/modwsgi
0 stars 0 forks source link

Fix memory leak in Adapter_output and Adapter_output_file #269

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I think I found two memory leaks when handling error after this line :
rv = ap_pass_brigade(r->output_filters, self->bb);

In the two functions linked below, the code exits early if rv != APR_SUCCESS,
without first freeing the brigade using apr_brigade_cleanup or 
apr_brigade_destroy.

The diagnostic seems to be consistent with the code sample available here :
http://httpd.apache.org/docs/trunk/developer/output-filters.html#nonblock
where we can see the rv value checked after freeing the brigade.

--------

function Adapter_output : 
http://code.google.com/p/modwsgi/source/browse/mod_wsgi/mod_wsgi.c#2980

function Adapter_output_file :
http://code.google.com/p/modwsgi/source/browse/mod_wsgi/mod_wsgi.c#3077

--------

The leak was discovered after having a wsgi worker suddenly consuming a lot of 
ram
just after having 3 occurrences of this error in apache logs :

mod_wsgi (pid=19667): Exception occurred processing WSGI script 
'/var/www/webgeoservices.com/current/script'.
IOError: failed to write data

Original issue reported on code.google.com by kmic...@webgeoservices.com on 19 Jul 2012 at 9:30

Attachments:

GoogleCodeExporter commented 8 years ago
Technically it should not cause a memory leak because of the way that Apache 
memory pools work.

The bucket brigade is allocated against the request object memory pool, 
although there may be linkage also to the connect object memory pool via the 
bucket allocator.

            self->bb = apr_brigade_create(r->pool,
                                          r->connection->bucket_alloc);

When the request finishes the memory pool will be automatically destroyed with 
all memory reclaimed. Thus that neither cleanup nor destroy were called 
explicitly shouldn't cause a leak of memory.

Further, any destructor like behaviour on any allocated objects will be called 
when the memory pool is destroyed. For bucket brigades this should mean that 
destroy is called if not already called.

The issue then should only be one of timing as to when destroy is called. That 
is, rather than being called at the point that the error is detected, it will 
be called when Apache finalises the request and destroys the memory pools.

Because an error occurred this should pretty well be immediately because all it 
is likely to do given that a partial response had already been written, is drop 
the connection. That the connection would be dropped and not reused for keep 
alive should mean that if any objects are associated with the connection memory 
pool they should also be destroyed.

So although calling destroy when the error occurred makes it more explicit, it 
is not strictly required. Even if it were called it will only release the 
memory back to the memory pool, with it only finally being released back to 
process as a whole when request finalised. Either way, it should not cause a 
memory leak.

Can you provide more information about whether wsgi.file_wrapper or normal 
iterable text response was being returned from the WSGI application. Also 
indicate what Python web framework you are using. Can see then if know of 
anything with specific framework being used that may have contributed to a 
growth in memory in this scenario.

Original comment by Graham.Dumpleton@gmail.com on 20 Jul 2012 at 4:45

GoogleCodeExporter commented 8 years ago
Closing old issue. Never seen any further evidence that this was specifically 
causing memory leakage. Still believed to be cleaned up automatically.

Original comment by Graham.Dumpleton@gmail.com on 12 Nov 2014 at 11:03