[CC to jda] Please can you recheck with a current gcc snapshot (from the gcc-snapshot package) and attach the preprocessed source?
Gerrit Pape writes: > Package: gcc > > This applies to gcc_3.2.3-6 and gcc_3.3.1-0pre0 on hppa; gcc_3.0.4-16 > doesn't have this problem. > > The dietlibc_0.22-2 builds with -Os by default on hppa, and this test > program linked against the dietlibc dies with a segfault after fopen(): > > #include <stdio.h> > int main() { > FILE *f; > fopen("foo", "a"); > fclose(f); > return(0); > } > > If the dietlibc is built without -Os, the program works fine. > > The bug is triggered by the following changes in > dietlibc/libstdio/fdglue2.c (I attach fdglue2.c for reference): > > diff -u -r1.10 -r1.11 > --- libstdio/fdglue2.c 9 Feb 2002 00:45:18 -0000 1.10 > +++ libstdio/fdglue2.c 4 Dec 2002 18:32:33 -0000 1.11 > @@ -1,5 +1,6 @@ > #include <unistd.h> > #include <fcntl.h> > +#include <sys/stat.h> > #include <errno.h> > #include "dietstdio.h" > #include <stdlib.h> > @@ -23,7 +24,12 @@ > tmp->bm=0; > tmp->bs=0; > tmp->buflen=BUFSIZE; > - tmp->flags=0; > + { > + struct stat st; > + fstat(fd,&st); > + tmp->flags=(S_ISFIFO(st.st_mode))?FDPIPE:0; > + } > + tmp->popen_kludge=0; > if (__stdio_atexit==0) { > __stdio_atexit=1; > atexit(__stdio_flushall); > > The dietlibc compiled with revision 1.10 doesn't segfault, revision 1.11 > does. > > The code changes look fine to me, and it works on other architectures, > so I suppose it's a problem with gcc version >=3.2 on hppa optimizing > the code. > > I've a complete test environment on paer, and did run this through gdb > several times. If you need more details, just ask for it, I should be > able to provide them. > > Regards, Gerrit. > #include <unistd.h> > #include <fcntl.h> > #include <sys/stat.h> > #include <errno.h> > #include "dietstdio.h" > #include <stdlib.h> > #include <pthread.h> > > extern int __stdio_atexit; > > FILE* __stdio_init_file_nothreads(int fd,int closeonerror); > FILE* __stdio_init_file_nothreads(int fd,int closeonerror) { > FILE *tmp=(FILE*)malloc(sizeof(FILE)); > if (!tmp) goto err_out; > tmp->buf=(char*)malloc(BUFSIZE); > if (!tmp->buf) { > free(tmp); > err_out: > if (closeonerror) close(fd); > errno=ENOMEM; > return 0; > } > tmp->fd=fd; > tmp->bm=0; > tmp->bs=0; > tmp->buflen=BUFSIZE; > { > struct stat st; > fstat(fd,&st); > tmp->flags=(S_ISFIFO(st.st_mode))?FDPIPE:0; > } > tmp->popen_kludge=0; > if (__stdio_atexit==0) { > __stdio_atexit=1; > atexit(__stdio_flushall); > } > tmp->next=__stdio_root; > __stdio_root=tmp; > tmp->ungotten=0; > return tmp; > } > > FILE* __stdio_init_file(int fd,int closeonerror) > __attribute__((weak,alias("__stdio_init_file_nothreads")));