Subject: bin/23988: egcs: cc -traditional totally broken
To: None <gnats-bugs@gnats.netbsd.org>
From: None <vax@carolina.rr.com>
List: netbsd-bugs
Date: 01/05/2004 06:05:49
>Number:         23988
>Category:       bin
>Synopsis:       egcs: cc -traditional totally broken
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 05 11:07:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     VaX#n8
>Release:        NetBSD 1.5.1
>Organization:
	
>Environment:
	
NetBSD-1.5.2 (don't know why it says 1.5.1 above in Release field above)

>Description:
	

In NetBSD-1.4, egcs-1.1.1 it was too buggy to compile small programs properly.
To convince yourself, try compiling "zap.c" or "zap2.c" (I forget which),
available at packetstormsecurity.  Apparently sizeof() was too complicated
for it to handle.

In NetBSD-1.5.2, use of the -traditional flag is too buggy to compile small
programs properly.  An example follows.  Please note that these kinds of
problems take HOURS to hunt down.  The bugs can go away by deleting a
seemingly inconsequential line.

This really blows.  Please reconsider use of egcs.  I used to do source-only
upgrades, but I had to stop that tradition due to egcs-1.1.1 on NetBSD-1.4.
Once again, I can't rely on the compiler.

The change to ELF binaries made upgrading difficult w/o recompiling
all my old binaries, but I worked around it with much less effort
than I've spent on this.  I'm no smarter after doing this, unfortunately,
and the program in question is no closer to working properly.

>How-To-Repeat:

This program tries to lseek an open file descriptor.  Thanks to
egcs, after gethostbyent, it appears that the kernel is returning
-1, and consulting errno gives various results depending on the
surrounding code.  I have gotten 22 (EINVAL) and -1 (ERESTART).

$ gcc -v
Using builtin specs.
gcc version egcs-2.91.66 19990314 (egcs-1.1.2 release)
$ cat > test.c <<EOM
#include <stdio.h>
#include <errno.h>

void tmp(void) {
  int fd;
  fd = open("/dev/null", 2, 0);
  printf("%d, %d, %d\n", fd, lseek(fd, 0, 0), errno);
}

main(argc,argv)
     int argc;
     char **argv;
{
    struct hostent *hp;

        tmp();
        hp=gethostbyname(argv[1]);
        tmp();
    exit(0);
}
EOM
$ rm a.out; cc -traditional test.c -o a.out; ./a.out localhost
4, 0, 0
5, -1, -1

>Fix:
Don't use egcs, or if you're stuck with it, don't use -traditional.
>Release-Note:
>Audit-Trail:
>Unformatted: