根据GNU C库,它允许分配给stdio
,就像它们是普通变量一样(我知道这是一个扩展)。我尝试了以下程序:
#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)
为什么gdb
没有报告stdout
的正确值?
进一步调查此处,我发现它似乎将stdout
存储在地址0x600940
,寻找struct _IO_FILE*
,我会找到一个与gdb
相同的指针报告为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
gdb
看来stdout
位于0x7ffff7dd7d90
,但实际上它位于0x600940
。
我正在使用GNU gdb (GDB) 7.4.1-debian
和gcc version 4.7.2 (Debian 4.7.2-5)
(x86-64)。
答案 0 :(得分: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
。