#4449: GHC 7 can't do IO when demonized
----------------------------+-----------------------------------------------
  Reporter:  kazu-yamamoto  |          Owner:  tibbe      
      Type:  bug            |         Status:  new        
  Priority:  normal         |      Milestone:  7.0.2      
 Component:  Compiler       |        Version:  7.1        
Resolution:                 |       Keywords:  forkProcess
  Testcase:                 |      Blockedby:             
Difficulty:                 |             Os:  MacOS X    
  Blocking:                 |   Architecture:  x86        
   Failure:  None/Unknown   |  
----------------------------+-----------------------------------------------

Comment(by adept):

 Replying to [comment:28 kazu-yamamoto]:
 > To narrow the problem, I made the following code. Please compile it on
 Snow Leopard with GHC 7.0.2rc1/-threaded. When you run it, you can see the
 following warnings:
 >
 > {{{
 > kqueue: kevent: invalid argument (Bad file descriptor)
 > kqueue: ioManagerWakeup: write: Bad file descriptor
 > kqueue: sendWakeup: invalid argument (Bad file descriptor)
 > kqueue: ioManagerDie: write: Bad file descriptor
 > }}}

 OK. I am able to reproduce this on FreeBSD 8.2, so I think it is something
 lurking in the BSD-only parts of code.

 First of all, I commented out the call to `new`, since `forkProcess`
 explicitly restarts IO manager after `fork`. Then I've run the sample code
 (compiled with GHC HEAD) under `truss` (observing cited error messages)
 and noticed that innermost (twice-forked) process performs a weird
 sequence of `close()`-s on its file descriptors:
 {{{
  4308: fork()                                    = 4310 (0x10d6)
  4310: kqueue(0x0,0x0,0x0,0x0,0x0,0x0)           = 3 (0x3)
  4310: fcntl(13,F_GETFL,)                        = 2 (0x2)
  4310: fcntl(13,F_SETFL,O_NONBLOCK|0x2)          = 0 (0x0)
  4310: fcntl(12,F_SETFD,FD_CLOEXEC)              = 0 (0x0)
  4310: fcntl(13,F_SETFD,FD_CLOEXEC)              = 0 (0x0)
  4310: fcntl(15,F_GETFL,)                        = 2 (0x2)
  4310: fcntl(15,F_SETFL,O_NONBLOCK|0x2)          = 0 (0x0)
  4310: fcntl(14,F_SETFD,FD_CLOEXEC)              = 454 (0x1c6)
  4310: fcntl(15,F_SETFD,FD_CLOEXEC)              = 0 (0x0)
  4310: write(15,"\M^?",1)                        = 1 (0x1)
  4310: read(14,"\M^?",4096)                      = 1 (0x1)
  4310: exit(0xf)                                 = 417 (0x1a1)
  4310: close(3)                                  = 0 (0x0)
  4310: close(4)                                  = 0 (0x0)
  4310: close(5)                                  = 0 (0x0)
  4310: close(6)                                  = 0 (0x0)
  4310: close(7)                                  = 0 (0x0)
  4310: close(3)                                  ERR#9 'Bad file
 descriptor'
  4310: close(8)                                  = 0 (0x0)
  4310: close(9)                                  = 0 (0x0)
  4310: close(10)                                 = 0 (0x0)
  4310: close(11)                                 = 0 (0x0)
  4310: read(14,"\M^?",4096)                      = 1 (0x1)
  4310: kevent(3,0x0,0,0x2887c010,64,{9.680145979 }) ERR#9 'Bad file
 descriptor'
  4310: close(3)                                  ERR#9 'Bad file
 descriptor'
  4310: close(12)                                 = 0 (0x0)
  4310: close(13)                                 = 0 (0x0)
  4310: close(14)                                 = 0 (0x0)
  4310: close(15)                                 = 0 (0x0)
  4310: open("/usr/local/lib/charset.alias",O_RDONLY,0666) = 3 (0x3)
  4310: fstat(3,{ mode=-r--r--r-- ,inode=49467,size=2209,blksize=16384 }) =
 0 (0x0)
  4310: read(3,"# This file contains"...,16384)   = 2209 (0x8a1)
  4310: read(3,0x28904000,16384)                  = 0 (0x0)
  4310: close(3)                                  = 0 (0x0)
  4310: ioctl(1,TIOCGETA,0xbf5f8ec8)              = 0 (0x0)
  4310: write(2,"kqueue: ",8)                     = 8 (0x8)
  4310: write(2,"kevent: invalid argument (Bad file descriptor)",46) = 46
 (0x2e)
  4310: write(2,"\n",1)                           = 1 (0x1)
  4310: write(15,"\M^?",1)                        ERR#9 'Bad file
 descriptor'
  4310: write(2,"kqueue: ",8)                     = 8 (0x8)
  4310: write(2,"ioManagerWakeup: write",22)      = 22 (0x16)
  4310: write(2,": Bad file descriptor\n",22)     = 22 (0x16)
  4310: write(15,"\M^?",1)                        ERR#9 'Bad file
 descriptor'
  4310: write(2,"kqueue: ",8)                     = 8 (0x8)
  4310: write(2,"sendWakeup: invalid argument (Bad file descriptor)",50) =
 50 (0x32)
  4310: write(2,"\n",1)                           = 1 (0x1)
  4310: write(13,"\M-~",1)                        ERR#9 'Bad file
 descriptor'
  4310: write(2,"kqueue: ",8)                     = 8 (0x8)
  4310: write(2,"ioManagerDie: write",19)         = 19 (0x13)
  4310: write(2,": Bad file descriptor\n",22)     = 22 (0x16)
  4310: process exit, rval = 1
  = 0 (0x0)
  4308: process exit, rval = 0
  = 0 (0x0)
  4307: process exit, rval = 0
 }}}

 Notice that kqueue FD (number 3) gets closed twice, then there is an
 attempt to use `kevent` on it, plus attempts to write to already-closed
 descriptors 13 and 15. I don't know yet what is the root cause of this,
 but I can tell you for sure that linux+epoll rts does not do anything even
 remotely similar.

 Full truss log is attached as well

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4449#comment:30>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to