logo       

[ ghc-Bugs-1219920 ] socketToHandle, hGetContents cause errors in ghci: msg#00060

lang.haskell.glasgow.bugs

Subject: [ ghc-Bugs-1219920 ] socketToHandle, hGetContents cause errors in ghci

Bugs item #1219920, was opened at 2005-06-13 14:34
Message generated for change (Comment added) made by pimlott
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=108032&aid=1219920&group_id=8032

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: libraries/network
Group: None
Status: Closed
Resolution: None
Priority: 5
Submitted By: Andrew Pimlott (pimlott)
Assigned to: Simon Marlow (simonmar)
Summary: socketToHandle, hGetContents cause errors in ghci

Initial Comment:
I wrote a server using socketToHandle and hGetContents.
The first request worked fine, but the second request
crashed with "internal error: scavenge_stack: weird
activation record found on stack: 9". I tried to
create a test case. I couldn't reproduce the same
problem, but I did get an intermittent "Bad file
descriptor". I think it may be a related problem, and
it may have to do with garbage collection (based on a
strace showing a call to getrusage).

The program is below, and when I run it with runghc and
feed it a line of input with nc, it crashes on the 17th
request. It's not important to me that you fix it; in
fact I only tried this as an experiment to simplify
some working code. But if you would like more
information, let me know.

I am using the Debian package ghc6 6.4-4.

import Network.Socket
import System.IO

main = do
s <- socket AF_INET Stream 0
h <- inet_addr "127.0.0.1"
bindSocket s (SockAddrInet 1236 h)
listen s 5
loop s

loop listenSock = do
(s,_) <- accept listenSock
h <- socketToHandle s ReadMode
input <- hGetContents h
putStrLn (take 10 input)
send s "got it\n"
sClose s
loop listenSock


----------------------------------------------------------------------

>Comment By: Andrew Pimlott (pimlott)
Date: 2005-07-07 11:53

Message:
Logged In: YES
user_id=498741

doh, thank you for the clear explanation!

----------------------------------------------------------------------

Comment By: Simon Marlow (simonmar)
Date: 2005-07-07 10:00

Message:
Logged In: YES
user_id=48280

It looks like a bug, but it has a rationale explanation.
After you call sClose, there is still a finalizer in the
system waiting to close the Handle. However, since the file
descriptor has been closed, it can be re-used by the next
call to accept, at which point the finalizer can run and
close a file descriptor that is in use again, leading to the
lazyRead error you see.

I've added some code to Network.Socket to prevent the use of
sClose and other socket operations after socketToHandle.

----------------------------------------------------------------------

Comment By: Andrew Pimlott (pimlott)
Date: 2005-07-06 12:00

Message:
Logged In: YES
user_id=498741

I should have detailed my test scenario, but what I see when
I run "echo hello world | nc localhost 1236" repeatedly is
that "hello worl" is printed 16 times, then

*** Exception: <socket: 5>: lazyRead: invalid argument (Bad
file descriptor)

So the error happens while trying to print out "input". As
I understand, input should keep a reference to h, which
should keep a reference to s, so nothing should get garbage
collected too soon. Moreover, something that happens later
(sClose) shouldn't be able to affect it. That said, when I
use hClose, or remove the close, I can't reproduce the
problem. So I'm perplexed. Can I ask you to explain in
more detail?

----------------------------------------------------------------------

Comment By: Simon Marlow (simonmar)
Date: 2005-07-06 05:57

Message:
Logged In: YES
user_id=48280

The "Bad file descriptor" error messages are to be expected:
when you turn a Socket into a Handle, it gets a finalizer
attached which closes the socket when the Handle is no
longer referenced. You want to call hClose h rather than
sClose s in the code above.

I've added some documentation for socketToHandle to reflect
this.

If you can reproduce the "scavenge_stack" error, please
follow up with more info, for now I'll close this bug.

----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=108032&aid=1219920&group_id=8032


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise