<div dir="ltr">Hello<div><br></div><div>Thanks for the really quick reply. The <span style="font-family:arial,sans-serif;font-size:13px">ngx_http_run_posted_requests totally made sense and explained the bit that I was missing.</span><div>
<span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div style><span style="font-family:arial,sans-serif">I get the bug when writev called in the context of a request handler gets an error.</span><span style="font-family:arial,sans-serif"> </span><font face="arial, sans-serif">The repro I had was basically with nginx running on a server and client on my laptop over wireless @ work. I am not @ work now and from my home connection I am unable to repro this. Will send you the backtrace as soon as I get it again.</font></div>
</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, May 24, 2013 at 8:24 PM, Maxim Dounin <span dir="ltr"><<a href="mailto:mdounin@mdounin.ru" target="_blank">mdounin@mdounin.ru</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br>
<div class="im"><br>
On Fri, May 24, 2013 at 07:09:58PM +0530, Fasih wrote:<br>
<br>
> Hi all<br>
><br>
> I have been seeing slow but steady socket leak in nginx ever since I<br>
> upgraded from 1.0.5 to 1.2.6. I have my custom module in nginx which I was<br>
> sure what was the leak. This is how I went about investigating:<br>
> 1. Configure nginx with one worker<br>
> 2. strace on the worker process, tracing<br>
> read/readv/write/writev/close/shutdown calls<br>
> 3. Every now and then, for all the open fds (from ls -l /proc/<pid>/fd),<br>
> check the socket that is not available in netstat -pane<br>
> 4. What I saw was, the leaking socket always had the last operation as<br>
> writev which returned an error.<br>
> 5. Increased the nginx log level to info and verified that nginx was<br>
> getting ECONNRESET or EPIPE on writev failure. Which was OK.<br>
> 6. Traced back in code to see how it is handled, the error translates to<br>
> CHAIN_ERROR and eventually causes ngx_http_finalize_request to be called.<br>
> This in turn calls ngx_http_terminate_request.<br>
><br>
> However, in this function, the request is not terminated if<br>
> r->write_event_handler is set. This seems to be set if the request handler<br>
> is a user module. I think the rationale for the check is, if there is a<br>
> module who is handling the request, dont terminate yet, wait for a write<br>
> event on the socket and then terminate it (which is why I thought it is<br>
> setting r->write_event_handler to ngx_http_terminate_handler).<br>
<br>
</div>Rationale is to make sure there are no functions on stack which<br>
assume request object is here and will try to access it after<br>
we'll free request data.<br>
<br>
The r->write_event_handler (that is, ngx_http_terminate_handler())<br>
is expected to be called by a ngx_http_run_posted_requests() which<br>
in turn is called by low-level event handling functions (notably,<br>
ngx_http_request_handler()).<br>
<div class="im"><br>
> I tried to repro this w/ empty_gif_handler however, it sends header and<br>
> body in one call to writev which I cant get to fail in my test environment.<br>
> To reproduce the bug, if I replace the call to ngx_http_send_response with<br>
> ngx_http_send_header and ngx_http_output_filter (as used by ngx_upstream or<br>
> other modules which dont have the headers and body together), I could<br>
> reproduce the leak. I have a client that sends a request and closes the<br>
> socket immediately, nginx sees the error, prints the info log, and then it<br>
> doesnt close the socket.<br>
><br>
> I have a small patch attached, the fix I did is basically saying that if<br>
> there is a connection error, there is no point setting write_event_handler<br>
> as there wont be any activity on the socket, so just terminate it<br>
> immediately.<br>
><br>
> I could be very wrong in the understanding of the code flow. My patch just<br>
> fixes this and I am not very sure if this is the right fix. Please let me<br>
> know.<br>
><br>
> I will try to add a testcase to reproduce this in the nginx test framework.<br>
<br>
</div>The patch looks wrong, see above.<br>
<br>
Could you please show a backtrace up to<br>
ngx_http_terminate_request() with mr->write_event_handler and<br>
c->error set (i.e. where you think leak happens)?<br>
<br>
You may also want to upgrade to a more recent version, e.g. 1.5.0,<br>
to make sure the problem you are facing isn't already fixed.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Maxim Dounin<br>
<a href="http://nginx.org/en/donation.html" target="_blank">http://nginx.org/en/donation.html</a><br>
<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org">nginx-devel@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-devel" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
</font></span></blockquote></div><br></div>