Zgodnie z biblioteką GNU C można przypisać do stdio
tak, jakby były zwykłymi zmiennymi (wiem, że jest to rozszerzenie). Próbowałem następujący program:Dlaczego gdb nie widzi, kiedy `stdio` został zmieniony?
#include <stdio.h>
int main()
{
stdout = NULL;
printf("Crash and %s\n", "burn");
return 0;
}
Po uruchomieniu program będzie wysypać zgodnie z oczekiwaniami, ale kiedy go uruchomić w gdb
wartość stdout
wciąż nie NULL
:
_IO_vfprintf_internal (s=0x0, format=0x400631 "Crash and %s\n", ap=0x7fffffffe210) at vfprintf.c:1297
1297 vfprintf.c: No such file or directory.
(gdb) print stdout
$1 = (struct _IO_FILE *) 0x7ffff7dd77a0
(gdb)
Dlaczego nie gdb
zgłoś poprawną wartość stdout
?
Badanie to dalej widzę, że wydaje się, aby zapisać stdout
pod adresem 0x600940
, szukając struct _IO_FILE*
tam znajdę wskaźnik, który jest taki sam jak gdb
raportach jako stdio
:
(gdb) print stdout
$1 = (struct _IO_FILE *) 0x7ffff7dd77a0
(gdb) print (void*)0x600940
$2 = (void *) 0x600940
(gdb) print (struct _IO_FILE*)0x600940
$3 = (struct _IO_FILE *) 0x600940
(gdb) print *(struct _IO_FILE**)0x600940
$4 = (struct _IO_FILE *) 0x7ffff7dd77a0
(gdb) n
7 puts("Crash and burn");
(gdb) print *(struct _IO_FILE**)0x600940
$5 = (struct _IO_FILE *) 0x0
(gdb) print &stdio
No symbol "stdio" in current context.
(gdb) print &stdout
$6 = (struct _IO_FILE **) 0x7ffff7dd7d90
tu wygląda gdb
sądzi, że stdout
znajduje się pod numerem 0x7ffff7dd7d90
, ale w rzeczywistości znajduje się pod adresem 0x600940
.
Używam GNU gdb (GDB) 7.4.1-debian
i gcc version 4.7.2 (Debian 4.7.2-5)
(x86-64).
Wypisuje dla mnie '(struct _IO_FILE *) 0x0', zgodnie z oczekiwaniami. Interesujące jest również to, że 'printf ("% s "," sd ");' działa dobrze, ale 'printf (" Awaria i% s \ n ", nagrywanie)' nie. Pokaż swoje wyjście z gdb. – Downvoter
@ cad Czy jest jakiś szczególny z mojego wyjścia 'gdb', które uważasz, że powinienem również dołączyć? Myślę, że twoja obserwacja może być związana z tym, co odkryłem, że 'puts' nie wydaje się respektować przypisania' stdout' ('printf ("% s "," sd ");' jest zoptymalizowane do użyj 'puts' zamiast' printf'). – skyking
Jeśli po prostu "uruchom" program - bez wchodzenia do printf lub kładzie ramki - co jest wyjście z 'print & stdout'? –