Ticket #109283 (new defect)

Opened 4 years ago

Last modified 4 years ago

Stack overflow, 100% CPU usage

Reported by: dastapov@… Owned by: somebody
Priority: major Milestone:
Component: component1 Version:
Keywords: Cc:

Description

I am investigating a "cabal update" breaking down with "Stack overflow". I've tracked the problem to a particular line referencing "browse" from Network.Browser.

After browsing through old bugs I've taken the test code from #8, simplifying it the tiniest bit: http://hpaste.org/paste/9447/simplified_a_bit#p40904

I am using HTTP 4000.0.9

Using this test code I attempted to download a 58 Mb test file which is being served with the following headers:

[23598] HTTP/1.1 200 OK [23598] Date: Tue, 26 Oct 2010 21:10:17 GMT [23598] Server: Apache/2.2.9 (Debian) mod_python/3.3.1 Python/2.5.2 [23598] Last-Modified: Tue, 26 Oct 2010 21:00:52 GMT [23598] ETag: "1888003-20a279-4938b67706900" [23598] Accept-Ranges: bytes [23598] Content-Type: application/x-tar [23598] Connection: close [23598] Proxy-Connection: close

If I serve the file with "Content-Length: xxxx", problem goes away.

I added "setDebugLog ..." to my request and noticed that with Content-Length file is read in one go using "readBlock", and without Content-Length file is being read with "readLine".

In both cases full contents of the file is shown in debug log. In both cases "closeOnEnd" is suspiciously missing from debug log.

If I try to "writeFile" response body to disk, I would get the whole file if it was served with Content-Length, or I would get 2-4K of it immediately if it was server WITHOUT Content-Length. After that program would either report "Stack overflow" or (provided that I ran it with +RTS -K400m) it will consume 100% CPU, outputting 1-2K of the file every 5-60 seconds.

Change History

Changed 4 years ago by dastapov@…

Re-formatting headers:

[23598]   HTTP/1.1 200 OK
[23598]   Date: Tue, 26 Oct 2010 21:10:17 GMT
[23598]   Server: Apache/2.2.9 (Debian) mod_python/3.3.1 Python/2.5.2
[23598]   Last-Modified: Tue, 26 Oct 2010 21:00:52 GMT
[23598]   ETag: "1888003-20a279-4938b67706900"
[23598]   Accept-Ranges: bytes
[23598]   Content-Type: application/x-tar
[23598]   Connection: close
[23598]   Proxy-Connection: close

Changed 4 years ago by dastapov@…

I've tracked this problem down to hopefulTransfer in Base.hs - since remote did not show Content-Length, "hopefulTransfer" is invoked immediately after response headers start coming in.

Since the file is quite large, and connection is quite slow, hopefulTransfer calls itself again and again without any pause, building up huge thunk on stack, which either results in StackOverflow? or takes an enormous time to unwind (if lots of stack is allocated).

I don't know enough of HTTP internals to try and fix this. Naive approach is to put threadDelay (1 sec) before recursive call to hopefulTransfer, which alleviates problem a bit. But this would just mean that a bigger file would be required to blow the stack, that's all.

Hope that you have something more constructive in mind.

Note: See TracTickets for help on using tickets.