weird egcs bug

Greg Bacon gbacon@itsc.uah.edu
Wed Mar 15 17:26:00 GMT 2000


I have a program that exhibits strange behavior when compiled with gcc.
Here's an excerpt:

int
get_word(int fd)
{
    char c;
    char word[MAXWORDLEN];    /* should be plenty of room */
    char *p;
    int  seen;
    int  ready;
    struct Node *w;

    ioctl(fd, FIONREAD, &ready);
    if (ready == 0)
        return 0;

    p    = word;
    seen = 0;
    do {
        if ( read(fd, &c, 1) < 0 )
            return 0;
        seen++;
    } while ( seen < sizeof(word) && (c != '\n') && (*p++ = c) );
    *p = '\0';

    if (!Tree)
        w = Tree = new_node(word);

    w = find_or_insert(Tree, word);
    w->freq++;

    return 1;
}

void
read_words(pid_t k1, int fd1, pid_t k2, int fd2)
{
    int retval;
    int kids = 2;
    int maxfd;
    fd_set rdrs;

    FD_ZERO(&rdrs);
    FD_SET(fd1, &rdrs);
    FD_SET(fd2, &rdrs);

    maxfd = fd1 > fd2 ? fd1 : fd2;
    maxfd++;

    while (kids) {
        /* UNCOMMENT THE NEXT LINE TO KILL BUG */
        /* printf("%d\n", kids); */
        retval = select(maxfd+1, &rdrs, NULL, NULL, NULL);

        if (retval < 0)
            err_abort(retval, "waiting for input from subprocesses");

        if ( FD_ISSET(fd1, &rdrs) ) {
            if (! get_word(fd1) ) {
                kids--;
                FD_CLR(fd1, &rdrs);
                close(fd1);
            }
        }

        if ( FD_ISSET(fd2, &rdrs) ) {
            if (! get_word(fd2) ) {
                kids--;
                FD_CLR(fd2, &rdrs);
                close(fd2);
            }
        }
    }

    waitpid(k1, NULL, 0);
    waitpid(k2, NULL, 0);
}

If I uncomment the printf line, control exits the loop as expected.
Without it, however, the program hangs.  When I run it in the
debugger, b read_words, run, c, I don't see the behavior!  When I just
run the code and interrupt it, I see

    Program received signal SIGINT, Interrupt.
    0x400c19ee in __select ()
    (gdb) where
    #0  0x400c19ee in __select ()
    #1  0x0 in ?? ()
    (gdb) 

I don't see where I might be overrunning a buffer to kill the stack
frame.

I see this behavior on

[19:22] subset% gcc --version
2.95.2
[19:22] subset% uname -a
IRIX64 subset 6.5 10181058 IP27

[19:33] ruby% gcc --version
egcs-2.91.66
[19:33] ruby% uname -a
Linux ruby.itsc.uah.edu 2.2.5-15 #1 Mon Apr 19 23:00:46 EDT 1999 i686 unknown

However, it runs as expected on

[19:23] hermes% gcc --version
egcs-2.91.66
[19:25] hermes% uname -a
SunOS hermes 5.7 Generic_106541-07 sun4u sparc SUNW,Ultra-5_10

I'm mystified.

Greg
-- 
Politicians and diapers have one thing in common. They should both be changed
regularly and for the same reason. 
    -- Gerry Brooks


More information about the Gcc-bugs mailing list