2016-02-02 12 views
6

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).

+0

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

+0

@ 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

+0

Jeśli po prostu "uruchom" program - bez wchodzenia do printf lub kładzie ramki - co jest wyjście z 'print & stdout'? –

Odpowiedz

0

Myślę, że twój gdb działa poprawnie. Spójrz na tych liniach ty cytowane:

_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) 

Podpis _IO_vfprintf_internal() ma strumień docelowy s jako pierwszy parametr. Ponieważ znajdujesz się na innym poziomie stosu, a stdout nie jest zmienną globalną, zostaje ponownie przydzielona. Ale widać, że Twoje zadanie zostało wstrzymane, ponieważ s=0x0.

Powiązane problemy