调试时GDB printf奇怪的输出
问题描述:
为什么printf的输出在出线时不显示?但在某些时候它没有印刷生产线16调试时GDB printf奇怪的输出
C文件:
#include<stdio.h>
void nextfunc(){
int ctr;
for(ctr = 0; ctr<3; ctr++){
printf("print ctr = %d",ctr);
}
printf("last print");
}
void main(){
int x;
printf("input x: ");
scanf("%d",&x);
printf("\nprint 2");
printf("\nprint 3");
nextfunc();
}
GDB:
(gdb) break main
Breakpoint 1 at 0x8048479: file file5.c, line 14.
(gdb) break nextfunc
Breakpoint 2 at 0x804843a: file file5.c, line 6.
(gdb) run
Starting program: /home/charmae/workspace/AVT/file5
Breakpoint 1, main() at file5.c:14
14 printf("input x: ");
(gdb) s
15 scanf("%d",&x);
(gdb) s
input x: 4
16 printf("\nprint 2");
(gdb) s
17 printf("\nprint 3");
(gdb) s
print 2
18 nextfunc();
(gdb) s
Breakpoint 2, nextfunc() at file5.c:6
6 for(ctr = 0; ctr<3; ctr++){
(gdb) s
7 printf("print ctr = %d",ctr);
(gdb) s
6 for(ctr = 0; ctr<3; ctr++){
(gdb) s
7 printf("print ctr = %d",ctr);
(gdb) s
6 for(ctr = 0; ctr<3; ctr++){
(gdb) s
7 printf("print ctr = %d",ctr);
(gdb) s
6 for(ctr = 0; ctr<3; ctr++){
(gdb) s
9 printf("last print");
(gdb) s
10 }
(gdb) s
main() at file5.c:19
19 }
(gdb) s
0x0014a113 in __libc_start_main() from /lib/i386-linux-gnu/libc.so.6
(gdb) s
Single stepping until exit from function __libc_start_main,
which has no line number information.
print 3print ctr = 0print ctr = 1print ctr = 2last print[Inferior 1 (process 2578) exited with code 012]
答
输出尽管stdout
被缓冲。这意味着它被保存在一个临时缓冲区中,直到缓冲区满了,打印一个换行符或调用函数fflush(stdout)
。程序结束时,也会自动刷新stdout
。
你输出打印在“错误的地方”在GDB的原因是因为这种缓冲。您应该在printf
格式字符串的末尾添加换行符,或者明确地呼叫fflush
。
答
的技巧是,你没有把一个换行符:
printf("last print");
标准IO库将缓冲输出,直到它看到要打印的换行符。输出到终端通常是线路缓冲的;可能gdb
运行该程序就好像它连接到一个终端,所以它会打印前面的行,其中包含\n
字符。
输出实际上在输出你有:在退出前
... ctr = 2last print[In ...
标准IO库刷新所有的输入流 - 通过atexit(3)
退出处理程序 - 这样的在程序要求操作系统拆除其内存并通知其父母已经死亡之前,输出会被刷新。
答
像printf这样的stdio函数被缓冲了,所以它只在遇到换行时才输出。
如果你想每printf
编辑后立即打印使用换行符\n
或fflush(stdout);
: Why does printf not flush after the call unless a newline is in the format string?
感谢您的参考。我发现这个导入,就像它提到的那样,即使标准输出是**不是**行缓冲(但是简单地缓冲),如果它已被重定向。 – alk