Re: library/6249: fcntl(2) called from threaded application can block forever

View: New views
2 Messages — Rating Filter:   Alert me  

Re: library/6249: fcntl(2) called from threaded application can block forever

by Joachim Schipper-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The following reply was made to PR library/6249; it has been noted by GNATS.

From: Joachim Schipper <joachim@...>
To: gnats@...
Cc:  
Subject: Re: library/6249: fcntl(2) called from threaded application can block forever
Date: Sun, 1 Nov 2009 13:44:27 +0100

 On Sun, Nov 01, 2009 at 12:24:05PM +0100, Michael Shuldman wrote:
 > >Number:         6249
 > >Category:       library
 > >Synopsis:       fcntl(2) called from threaded application can block forever
 > >Confidential:   yes
                    ^^^
 
 This doesn't seem to have done anything.
 
 > >Description:
 >         As shown by the stacktrace below, the application was calling
 >         strerror(3), which as part of it's work appears to have
 >         been calling close(2) on fd 18.  At this point the process was
 >         interrupted by a signal.
 >
 >         In the signal handler it the processes received a new
           ^^^^^^^^^^^^^^^^^^^^^
 >         filedescriptor via recvmsg(2) from another process.  This
                              ^^^^^^^^^^
 >         new filedescriptor also got assigned the index 18, the same
 >  index as strerror(3) was closing.
 >
 >         It then performed a fcntl(2) call on the received fd, but
 >         this fcntl(2) call ends up blocking for what appears to be
 >         forever.
 >
 >         Note that while this is with the patch received from Kurt
 >         Miller with regards to bug library/6238, I have no reason
 >         to think this problem is caused by that patch, as I have
 >         seen the same problem many times before applying the patch
 >         also.
 
 recvmsg(2) is not listed as safe for use in signal handlers, see
 signal(3). (It will, unless you use sigaction(2) to unset the SA_RESTART
 flag, be automatically restarted if a signal arrives while it is
 executing; that is unrelated.)
 
 Am I misunderstanding something fundamental? It looks like you just have
 a bug in your program. Perhaps you replaced a read() by a recvmsg()?
 read(2) is signal-safe...
 
  Joachim
 
 > #0  0x0afe08f1 in poll () from /usr/lib/libc.so.50.1
 > #1  0x0cefd558 in _thread_kern_poll (wait_reqd=1)
 >     at /usr/src/lib/libpthread/uthread/uthread_kern.c:760
 > #2  0x0cefd097 in _thread_kern_sched (scp=0x0)
 >     at /usr/src/lib/libpthread/uthread/uthread_kern.c:382
 > #3  0x0cefd3e3 in _thread_kern_sched_state (state=PS_POLL_WAIT,
 >     fname=0x9 <Address 0x9 out of bounds>, lineno=9)
 >     at /usr/src/lib/libpthread/uthread/uthread_kern.c:550
 > #4  0x0cefedb4 in _spinlock_debug (lck=0x7da5b550,
 >     fname=0x2ceee080 "/usr/src/lib/libpthread/uthread/uthread_fd.c",
 >     lineno=401) at /usr/src/lib/libpthread/uthread/uthread_spinlock.c:102
 > #5  0x0cef9934 in _thread_fd_table_init (fd=18, init_mode=FD_INIT_UNKNOWN,
 >     status_flags=0x0) at /usr/src/lib/libpthread/uthread/uthread_fd.c:401
 > #6  0x0cef9e41 in _thread_fd_lock (fd=18, lock_type=3, timeout=0x0)
 >     at /usr/src/lib/libpthread/uthread/uthread_fd.c:679
 > #7  0x0cef6302 in fcntl (fd=18, cmd=1)
 >     at /usr/src/lib/libpthread/uthread/uthread_fcntl.c:55
 > #8  0x000e3d2f in fdisopen (fd=18) at ../lib/util.c:1012
 > #9  0x000dc1f7 in sigio (sig=23, sip=0x2cef46ac, scp=0xcfbf7a0c)
 >     at ../lib/connectchild.c:1061
 > #10 0x0cefebd7 in _dispatch_signal (sig=23, scp=0xcfbf7a0c)
 >     at /usr/src/lib/libpthread/uthread/uthread_sig.c:396
 > #11 0x0cefecc2 in _dispatch_signals (scp=0xcfbf7a0c)
 > ---Type <return> to continue, or q <return> to quit---
 >     at /usr/src/lib/libpthread/uthread/uthread_sig.c:425
 > #12 0x0cefe4b8 in _thread_sig_handler (sig=23, info=0xcfbf7a5c, scp=0xcfbf7a0c)
 >     at /usr/src/lib/libpthread/uthread/uthread_sig.c:139
 > #13 <signal handler called>
 > #14 0x0afe0ff5 in close () from /usr/lib/libc.so.50.1
 > #15 0x0cef5c4c in close (fd=18)
 >     at /usr/src/lib/libpthread/uthread/uthread_close.c:65
 > #16 0x0b020ae7 in load_msgcat (path=0xcfbf7e00 "/usr/share/nls/C/libc.cat")
 >     at /usr/src/lib/libc/nls/catopen.c:133
 > #17 0x0b02092c in _catopen (name=0x2afb04cd "libc", oflag=0)
 >     at /usr/src/lib/libc/nls/catopen.c:104
 > #18 0x0b02056f in __num2string (num=35, sign=1, setid=1,
 >     buf=0x2afdb900 "Resource temporarily unavailable", buflen=255, list=0x0,
 >     max=91, def=0x2afb04d2 "Unknown error: ")
 >     at /usr/src/lib/libc/string/strerror_r.c:78
 > #19 0x0b02066f in strerror_r (errnum=35,
 >     strerrbuf=0x2afdb900 "Resource temporarily unavailable", buflen=255)
 >     at /usr/src/lib/libc/string/strerror_r.c:122
 > #20 0x0b01e47a in strerror (num=35) at /usr/src/lib/libc/string/strerror.c:39


Re: library/6249: fcntl(2) called from threaded application can block forever

by Mark Kettenis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Date: Sun, 1 Nov 2009 06:05:01 -0700 (MST)
> From: Joachim Schipper <joachim@...>
>
>  recvmsg(2) is not listed as safe for use in signal handlers, see
>  signal(3). (It will, unless you use sigaction(2) to unset the SA_RESTART
>  flag, be automatically restarted if a signal arrives while it is
>  executing; that is unrelated.)
>  
>  Am I misunderstanding something fundamental? It looks like you just have
>  a bug in your program. Perhaps you replaced a read() by a recvmsg()?
>  read(2) is signal-safe...

POSIX says that recmsg(2) is signal safe as well, which makes sense.
And I don't see why it wouldn't be on OpenBSD.  Except that the
threads library might screw up here of course.