2016-02-02 3 views
6

GNU Cライブラリによれば、普通の変数と同じようにstdioに割り当てることができます(これは拡張機能です)。プログラムを実行する場合は、予想通り、それはセグメンテーションフォールトます`stdio`がいつ変更されるのをgdbが見ないのですか?

#include <stdio.h> 
int main() 
{ 
    stdout = NULL; 

    printf("Crash and %s\n", "burn"); 

    return 0; 
} 

が、私はgdbでそれを実行するとstdoutの値がまだ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) 

しないのはなぜgdbstdoutの正しい値を報告しますか?

(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 

ここでは、次のようになります。これは、さらに私はstdioとしてgdbレポートと同じだポインタを見つけるだろうがstruct _IO_FILE*を探して、アドレス0x600940stdoutを保存するように見えることがわかり調査

gdbstdout0x7ffff7dd7d90にあると考えますが、実際には0x600940にあります。

私はGNU gdb (GDB) 7.4.1-debiangcc version 4.7.2 (Debian 4.7.2-5)(x86-64)を使用しています。

+0

私は 'struct _IO_FILE *)0x0'を期待通りに表示します。興味深いのは 'printf("%s "、" sd ");はうまくいきますが、printf("クラッシュと%s \ n " gdbの出力を表示してください。 – Downvoter

+0

@cad私の 'gdb'出力から、あなたも私も含めなければならないと思いますか?あなたの所見はこれに関連していると思います。私が見つけたのは、 'puts'は' stdout'の割り当てを尊重していないようです( 'printf("%s "、" sd ");' 'printf'の代わりに' puts'を使います)。 – skyking

+0

printfやputsフレームに入れずにプログラムを 'start'するだけなら、' print&stdout'の出力は何ですか? –

答えて

0

あなたのgdbは正しく機能していると思います。あなたが引用されたこれらの行を見てください:

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

_IO_vfprintf_internal()の署名が最初のパラメータとして先ストリームsを持っています。あなたはスタックの異なるレベルにあり、stdoutはグローバル変数ではないため、再割り当てされます。しかし、s=0x0という理由で割り当てが保留になったことがわかります。

関連する問題