[prev in list] [next in list] [prev in thread] [next in thread] 

List:       redhat-devel
Subject:    Re: Glibc, fetish and fpending = SIGSEGV?
From:       Michael Tokarev <mjt () tls ! msk ! ru>
Date:       2001-12-22 2:37:39
[Download RAW message or body]

Folks, I'm totally stuck.  I don't understand what's going on.
I spent the whole day and a night trying to understand something,
rebuilding/downloading/etc/etc the glibc, gcc, binutils, with
no awail.  A mystery.

What I have now is as follows.

I have glibc-2.2.4-19 compiled by gcc-2.96-97 that works just fine.
It has no debugging information (strip was made in order to be able
to send it to 60+ dialup machines).

I wrote a trivial program to test the stuff:

 #include <stdio.h>
 #include <stdio_ext.h>
 int main() { return __fpending(stdout); }

When I run it under gdb with that 2.2.4-19 glibc, both stdout
and &_IO_2_1_stdout_ are the same and there is no _IO_stdout_:

 (gdb) printf "%p\n", stdout
 0x40149660
 (gdb) printf "%p\n", &_IO_2_1_stdout_
 0x40149660
 (gdb) printf "%p\n", &_IO_stdout_
 No symbol "_IO_stdout_" in current context.

Program completes just fine, returning 0.

But when I run this with just-compiled 2.2.4-19, with complete
debugging info, I got:

 LD_LIBRARY_PATH=. gdb ./a.out
 ...
 (gdb) printf "%p\n", stdout
 0x40148980
 (gdb) printf "%p\n", &_IO_stdout_
 0x40148980
 (gdb) printf "%p\n", &_IO_2_1_stdout_
 0x401485e0

As you see, stdout now points to _IO_stdout, that IS defined now.

Well ok.  Looking into source (only stdout, stdin and stderr skipped):

libio.h:
 extern struct _IO_FILE_plus _IO_2_1_stdout_;
 #ifndef _LIBC
 #define _IO_stdout ((_IO_FILE*)(&_IO_2_1_stdout_))
 #else
 extern _IO_FILE *_IO_stdout;
 #endif

stdio.c:
 _IO_FILE *stdout = (FILE *) &_IO_2_1_stdout_;
 #ifdef _LIBC
 strong_alias (stdout, _IO_stdout);
 #endif

oldstdfile.c:
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_, _IO_NO_READS);
 static void _IO_check_libio __P ((void)) __attribute__ ((constructor)) {
   if (&_IO_stdin_used == NULL) {
      /* We are using the old one. */
      _IO_stdout = stdout = (_IO_FILE *) &_IO_stdout_;
   }
 #endif


I know the difference between "good" glibc and any I tried now --
good one, in order to be smaller, was built with --enable-oldest-abi=2.1.3,
so the oldstdfile.c stuff wasn't compiled in (just realized this
looking to the last #if statement, and started a compilation process
again).

The Question.  How the above symbol hell is supposed to work?  And why
the code in oldstdfile resets pointers in this simple program above
and in all fetish programs, so that __fpending, that expects to see
new file structure actually sees a garbage made from old file structure?
And, at the end, how this code actually works at other places?!?!

Can someone *please* explain what's going on here?  I'm not a novice
but this situation isn't that perfect...

Thank you.

Regards,
 Michael.



_______________________________________________
Redhat-devel-list mailing list
Redhat-devel-list@redhat.com
https://listman.redhat.com/mailman/listinfo/redhat-devel-list
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic