0

I am encountering a problem to understand what the file pointers stdin, stdout and stderr mean and how they are loaded into the memory. The program

#include <stdio.h>

int main(void) {
    printf("stdin = %p\n", (void *) stdin);
    printf("stdout = %p\n", (void *) stdout);
    printf("stderr = %p\n", (void *) stderr);
    return 0;
}

outputs

stdin = 0x7ffff7fa29a0
stdout = 0x7ffff7fa36c0
stderr = 0x7ffff7fa35e0

What I know is that stdin,stdout and stderr somehow correspond to the file descriptors 0, 1, and 2. However, if I print the value under the given address (e.g. for stdin) with gdb then I get the following line:

0x7ffff7fa29a0 <_IO_2_1_stdin_>:    0x00000000fbad2088

What is _IO_2_1_? If 0 is a file descriptor for stdin, what is 0xfbad2088?

Furthermore, I take a look at the symbols with readelf and get the following line:

25: 0000000000004050     8 OBJECT  GLOBAL DEFAULT   26 stdin@GLIBC_2.2.5

I thought libc is a bunch of functions. Why does a file/pointer stands in GOT?

At what time the file pointers stdin, stdout and stderr are loaded into memory and why do I cannot find any 0, 1 and 2 when debugging?

jupiter_jazz
  • 281
  • 1
  • 8
  • Try this: `printf("%d %d %d\n", fileno(stdin), fileno(stdout), fileno(stderr));` – Steve Summit Jun 02 '22 at 20:22
  • They're `FILE*` (which you know because `man stdin` tells you that, if it wasn't already obvious), which means they point to an object of `typedef` `FILE`. Normally, `FILE` is a `struct` and it's not defined in any user-visible header because it has no user-visible members. (It could be a `union`, or even a primitive compiler-internal type.) By the same token, `_IO_2_1_stdin_` is a globally-visible name for a `FILE` object, which is defined in the Gnu libc implementation. (There are other data objects in the library, too. Libraries can contain static data members as well as functions.) – rici Jun 02 '22 at 20:23
  • This might also work: `printf("%d %d %d\n", stdin->_file, stdout->_file, stderr->_file);`. (But this is not only nonportable, it's guaranteed not to work everywhere, as it involves accessing private, implementation-specific details which ordinary programs shouldn't care about.) – Steve Summit Jun 02 '22 at 20:26
  • so, is like `0x7ffff7fa29a0` a pointer to the `_IO_FILE struct` from `struct_FILE.h`? Why and at what point it is loaded to the memory then? @SteveSummit, thank you, I am wondering about the offset of `fileno` and why `_flags` stand first in the struct... :) – jupiter_jazz Jun 02 '22 at 20:32

0 Answers0