如何告诉GDB刷新被调试程序的stdio

时间:2011-11-24 01:32:22

标签: debugging gdb buffer stdio

stdio通常是缓冲的。当我遇到一个断点并且在断点之前有一个printf时,打印的字符串可能仍然在缓冲区中,我看不到它。

我知道我可以通过在程序中添加一些刷新代码来刷新stdio。 如果不这样做,有没有办法告诉GDB在GDB停止后刷新被调试程序的stdio?调试程序时,这种方式更友好。

4 个答案:

答案 0 :(得分:9)

如果您调用fflush(NULL)

,许多最近的UNIX stdio实现将刷新所有缓冲区
(gdb) call fflush(0)

但通常你不应该这样做:如果你打电话给printf(而不是fprintf),那就是stdout,这会转到你的终端,这通常是行缓冲。因此,只要您的printf打印了一个新行,缓冲区就会在printf返回后刷新。

答案 1 :(得分:3)

GDB允许您直接从命令行调用C函数。所以你可以做到

(gdb) call setbuf(stdout, NULL)

现在,唯一的问题是我不知道在运行时“获取”stdout真实值的方法。

编辑这可能会有所帮助(来自the docs):

call setbuf(fdopen(1, "w"), 0)

答案 2 :(得分:1)

如果您在程序中定义了一个功能:

void flush_all(void) {
    fflush(NULL);
}

您可以在gdb(1)内使用:

调用此函数
call flush_all()

一个简短的演示:

$ cat cat.c
#include <stdio.h>

int main(int argc, char* argv[]) {
    printf("this is a partial write");
    printf("this is a partial write");
    printf("this is a partial write");
    printf("this is a partial write");
    printf("this is a partial write");

    return 0;
}

void flush_all(void) {
    fflush(NULL);
}

$ gcc -g -o cat cat.c
$ gdb
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file cat
Reading symbols from /home/sarnold/tmp/cat...done.
(gdb) break printf
Breakpoint 1 at 0x400428
(gdb) run
Starting program: /home/sarnold/tmp/cat 

Breakpoint 1, __printf (format=0x4006bc "this is a partial write") at printf.c:30
30  printf.c: No such file or directory.
    in printf.c
(gdb) cont
Continuing.

Breakpoint 1, __printf (format=0x4006bc "this is a partial write") at printf.c:30
30  in printf.c
(gdb) cont
Continuing.

Breakpoint 1, __printf (format=0x4006bc "this is a partial write") at printf.c:30
30  in printf.c
(gdb) call flush_all()
this is a partial writethis is a partial write(gdb) ^CQuit
(gdb) quit

答案 3 :(得分:0)

您可以像在display中一样使用(gdb) display命令,其详细信息可以在here中找到。 GDB碰到行尾字符(例如“ \ n”)后,将显示输出。您可以使用undisplay关闭显示。