Opened 10 years ago

Closed 10 years ago

#1149 closed bug (fixed)

Socket handles are not properly closed after hDuplicate

Reported by: cb224@… Owned by: igloo
Priority: normal Milestone: 6.6.1
Component: libraries/network Version: 6.6
Keywords: Cc:
Operating System: Linux Architecture: x86
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


After accepting a handle using Network's accept, then using hDuplicate from GHC.Handle to get separate read/write channels, hClose on both Handles does not appear to properly close the socket.

$ cat >bug.hs
import GHC.Handle (hDuplicate)
import Network
import System.IO

main = serve 1234

serve port
    = withSocketsDo $
      do gate <- listenOn (PortNumber port)
         accept_clients gate
    where accept_clients gate
              = do (h,host,port) <- accept gate
                   let h_in  = h
                       h_out = h
                   h_out <- hDuplicate h
                   hClose h_in
                   hClose h_out
                   accept_clients gate

compile, run, and connect:

$ ghc --make -o bug -v bug.hs
Glasgow Haskell Compiler, Version 6.6, for Haskell 98, compiled by GHC version 6
Using package config file: /usr/lib/ghc-6.6/package.conf
wired-in package base mapped to base-2.0
wired-in package rts mapped to rts-1.0
wired-in package haskell98 mapped to haskell98-1.0
wired-in package template-haskell mapped to template-haskell-2.0
Hsc static flags: -static
*** Chasing dependencies:
Chasing modules from: bug.hs
Stable obj: []
Stable BCO: []
compile: input file bug.hs
Created temporary directory: /tmp/ghc2719_0
*** Checking old interface for main:Main:
[1 of 1] Compiling Main             ( bug.hs, bug.o )
*** Parser:
*** Renamer/typechecker:
*** Desugar:
    Result size = 95
*** Simplify:
    Result size = 117
    Result size = 99
*** Tidy Core:
    Result size = 99
*** CorePrep:
    Result size = 123
*** Stg2Stg:
*** CodeGen:
*** CodeOutput:
*** Assembler:
gcc -I. -c /tmp/ghc2719_0/ghc2719_0.s -o bug.o
*** Deleting temp files:
Deleting: /tmp/ghc2719_0/ghc2719_0.s
Upsweep completely successful.
*** Deleting temp files:
link: linkables are ...
LinkableM (Thu Feb 15 09:30:11 GMT 2007) main:Main
   [DotO bug.o]
Linking bug ...
*** Linker:
gcc -v -o bug -DDONT_WANT_WIN32_DLL_SUPPORT bug.o -L/usr/lib/network-2.0/ghc-6.6
 -L/usr/lib/ghc-6.6 -lHSnetwork-2.0 -lHSparsec -lHSbase -lHSbase_cbits -lHSrts -
lm -lgmp -ldl -lrt -u base_GHCziBase_Izh_static_info -u base_GHCziBase_Czh_stati
c_info -u base_GHCziFloat_Fzh_static_info -u base_GHCziFloat_Dzh_static_info -u 
base_GHCziPtr_Ptr_static_info -u base_GHCziWord_Wzh_static_info -u base_GHCziInt
_I8zh_static_info -u base_GHCziInt_I16zh_static_info -u base_GHCziInt_I32zh_stat
ic_info -u base_GHCziInt_I64zh_static_info -u base_GHCziWord_W8zh_static_info -u
 base_GHCziWord_W16zh_static_info -u base_GHCziWord_W32zh_static_info -u base_GH
CziWord_W64zh_static_info -u base_GHCziStable_StablePtr_static_info -u base_GHCz
iBase_Izh_con_info -u base_GHCziBase_Czh_con_info -u base_GHCziFloat_Fzh_con_inf
o -u base_GHCziFloat_Dzh_con_info -u base_GHCziPtr_Ptr_con_info -u base_GHCziPtr
_FunPtr_con_info -u base_GHCziStable_StablePtr_con_info -u base_GHCziBase_False_
closure -u base_GHCziBase_True_closure -u base_GHCziPack_unpackCString_closure -
u base_GHCziIOBase_stackOverflow_closure -u base_GHCziIOBase_heapOverflow_closur
e -u base_GHCziIOBase_NonTermination_closure -u base_GHCziIOBase_BlockedOnDeadMV
ar_closure -u base_GHCziIOBase_BlockedIndefinitely_closure -u base_GHCziIOBase_D
eadlock_closure -u base_GHCziIOBase_NestedAtomically_closure -u base_GHCziWeak_r
unFinalizzerBatch_closure -u base_GHCziConc_ensureIOManagerIsRunning_closure
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c
++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/l
ib --without-included-gettext --enable-threads=posix --enable-nls --program-suff
ix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --en
able-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
 /usr/lib/gcc/i486-linux-gnu/4.1.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-
linker /lib/ -o bug -u base_GHCziBase_Izh_static_info -u base_GHCzi
Base_Czh_static_info -u base_GHCziFloat_Fzh_static_info -u base_GHCziFloat_Dzh_s
tatic_info -u base_GHCziPtr_Ptr_static_info -u base_GHCziWord_Wzh_static_info -u
 base_GHCziInt_I8zh_static_info -u base_GHCziInt_I16zh_static_info -u base_GHCzi
Int_I32zh_static_info -u base_GHCziInt_I64zh_static_info -u base_GHCziWord_W8zh_
static_info -u base_GHCziWord_W16zh_static_info -u base_GHCziWord_W32zh_static_i
nfo -u base_GHCziWord_W64zh_static_info -u base_GHCziStable_StablePtr_static_inf
o -u base_GHCziBase_Izh_con_info -u base_GHCziBase_Czh_con_info -u base_GHCziFlo
at_Fzh_con_info -u base_GHCziFloat_Dzh_con_info -u base_GHCziPtr_Ptr_con_info -u
 base_GHCziPtr_FunPtr_con_info -u base_GHCziStable_StablePtr_con_info -u base_GH
CziBase_False_closure -u base_GHCziBase_True_closure -u base_GHCziPack_unpackCSt
ring_closure -u base_GHCziIOBase_stackOverflow_closure -u base_GHCziIOBase_heapO
verflow_closure -u base_GHCziIOBase_NonTermination_closure -u base_GHCziIOBase_B
lockedOnDeadMVar_closure -u base_GHCziIOBase_BlockedIndefinitely_closure -u base
_GHCziIOBase_Deadlock_closure -u base_GHCziIOBase_NestedAtomically_closure -u ba
se_GHCziWeak_runFinalizzerBatch_closure -u base_GHCziConc_ensureIOManagerIsRunni
ng_closure /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crt1.o /usr/lib/gcc
/i486-linux-gnu/4.1.2/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.1.2/c
rtbegin.o -L/usr/lib/network-2.0/ghc-6.6 -L/usr/lib/ghc-6.6 -L/usr/lib/gcc/i486-
linux-gnu/4.1.2 -L/usr/lib/gcc/i486-linux-gnu/4.1.2 -L/usr/lib/gcc/i486-linux-gn
u/4.1.2/../../../../lib -L/lib/../lib -L/usr/lib/../lib bug.o -lHSnetwork-2.0 -l
HSparsec -lHSbase -lHSbase_cbits -lHSrts -lm -lgmp -ldl -lrt -lgcc --as-needed -
lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/
i486-linux-gnu/4.1.2/crtend.o /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/
link: done
*** Deleting temp files:
*** Deleting temp dirs:
Deleting: /tmp/ghc2719_0

$ ./bug &
$ nc -vv localhost 1234
localhost.localdomain [] 1234 (?) open
[hangs indefinitely]

If the hDuplicate line above is removed:

$ nc -vv localhost 1234
localhost.localdomain [] 1234 (?) open
 sent 0, rcvd 0

Am using:

$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
$ uname -a
Linux 2.6.18-4-686 #1 SMP Fri Feb 2 15:10:49 UTC 2007 i686 GNU/Linux

Change History (3)

comment:1 Changed 10 years ago by igloo

Milestone: 6.6.1

Confirmed (amd64/Linux).

comment:2 Changed 10 years ago by igloo

Owner: set to igloo

comment:3 Changed 10 years ago by igloo

Resolution: fixed
Status: newclosed

It turns out hDuplicate was giving us a different FD for reading and writing, but we were only closing one of them. Now fixed in the HEAD and 6.6 branch. Thanks!

Note: See TracTickets for help on using tickets.