Re: gaim build problem, file descriptor issue

From: Dag-Erling Smørgrav <des_at_des.no>
Date: Sat, 17 Jan 2004 01:15:45 +0100
des_at_des.no (Dag-Erling Smørgrav) writes:

> Randy Bush <randy_at_psg.com> writes:
>> shell/environment dependency?
>
> No, same shell everywhere.
>
> BTW, I've traced this to kern_fcntl() (from fcntl(F_DUPFD) called very
> early in a newly-forked sh) returning EBADF, which suggests a bug in
> fdcopy().  The child expects file descriptor 5 to be in use, but it
> isn't.

OK, I'm starting to suspect that this is actually a bug in /bin/sh
which, for some strange reason, the new fdalloc code exposes.  Below
is an annotated trace.

Up to here, sh has been processing the parts of configure that parse
command-line options and try to determine if you want a help message
or the script version.  The trace begins as sh is in the middle of an
if block that begins with "if $ac_init_version", which is false is
false (because I did not specify --version), so sh is busy skipping
ahead to the "fi":

  1004 sh       CALL  read(0x5,0x806d000,0x3ff)
  1004 sh       GIO   fd 5 read 1023 bytes
       "992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
        Free Software Foundation, Inc.
        This configure script is free software; the Free Software Foundation
        gives unlimited permission to copy, distribute and modify it.
        _ACEOF
          exit 0
        fi
        exec 5>config.log
        cat >&5 <<_ACEOF
        This file contains any messages produced by compilers while
        running configure, to aid debugging if configure makes a mistake.

        It was created by $as_me, which was
        generated by GNU Autoconf 2.53.  Invocation command line was

          $ $0 $_at_

        _ACEOF
        {
        cat <<_ASUNAME
        ## --------- ##
        ## Platform. ##
        ## --------- ##

        hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
        uname -m = `(uname -m) 2>/dev/null || echo unknown`
        uname -r = `(uname -r) 2>/dev/null || echo unknown`
        uname -s = `(uname -s) 2>/dev/null || echo unknown`
        uname -v = `(uname -v) 2>/dev/null || echo unknown`

        /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
        /bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`

        /bin/arch              = `(/bin/a"
  1004 sh       RET   read 1023/0x3ff

The last (truncated) line is line 988, which is where sh incorrectly
reports the bug.  While it the input routine has reached line 988, sh
is actually just about to execute the following lines:

exec 5>config.log
cat >&5 <<_ACEOF
...
_ACEOF

  1004 sh       CALL  open(0x806c640,0x601,0x1b6)
  1004 sh       NAMI  "config.log"
  1004 sh       RET   open 6
  1004 sh       CALL  close(0x5)
  1004 sh       RET   close 0
  1004 sh       CALL  fcntl(0x6,0,0x5)
  1004 sh       RET   fcntl 5
  1004 sh       CALL  close(0x6)
  1004 sh       RET   close 0

The above is sh opening config.log, finding out that it didn't get the
descriptor it wants (5, because of the "5>"), and moving config.log
from descriptor 6 to descriptor 5.

  1004 sh       CALL  stat(0x806c768,0xbfbfe7d0)
  1004 sh       NAMI  "/usr/local/bin/cat"
  1004 sh       RET   stat -1 errno 2 No such file or directory
  1004 sh       CALL  stat(0x806c768,0xbfbfe7d0)
  1004 sh       NAMI  "/usr/local/sbin/cat"
  1004 sh       RET   stat -1 errno 2 No such file or directory
  1004 sh       CALL  stat(0x806c768,0xbfbfe7d0)
  1004 sh       NAMI  "/bin/cat"
  1004 sh       RET   stat 0

This is sh looking for cat(1) and finding it in /bin.  Funny how it's
always in the last place you look...

  1004 sh       CALL  fork
  1004 sh       RET   fork 1123/0x463
  1123 sh       RET   fork 0
  1004 sh       CALL  getpgrp
  1004 sh       RET   getpgrp 1004/0x3ec
  1004 sh       CALL  wait4(0xffffffff,0xbfbfe808,0x2,0)

the parent sh forks off a child to run cat(1)

  1123 sh       CALL  close(0x5)
  1123 sh       RET   close 0
  1123 sh       CALL  close(0x4)
  1123 sh       RET   close 0
  1123 sh       CALL  close(0x1)
  1123 sh       RET   close 0

the child does some housekeeping

  1123 sh       CALL  fcntl(0x5,0,0x1)
  1123 sh       RET   fcntl -1 errno 9 Bad file descriptor

hey!  we just closed that descriptor!

  1123 sh       CALL  write(0x2,0x806b180,0x2b)
  1123 sh       GIO   fd 2 wrote 43 bytes
       "./configure.lineno: 5: Bad file descriptor
       "
  1123 sh       RET   write 43/0x2b
  1123 sh       CALL  exit(0x2)
  1004 sh       RET   wait4 1123/0x463
  1004 sh       CALL  read(0x5,0x806d000,0x3ff)
  1004 sh       RET   read -1 errno 9 Bad file descriptor
  1004 sh       CALL  write(0x2,0x806b180,0x45)
  1004 sh       GIO   fd 2 wrote 69 bytes
       "./configure.lineno: 988: Syntax error: EOF in backquote substitution
       "
  1004 sh       RET   write 69/0x45
  1004 sh       CALL  exit(0x2)

DES
-- 
Dag-Erling Smørgrav - des_at_des.no
Received on Fri Jan 16 2004 - 15:16:15 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:38 UTC