Как сообщить GDB, чтобы очистить stdio от отлаживаемой программы

Обычно stdio буферизуется. Когда я ударяю точку останова, и там есть printf перед точкой останова, печатная строка все еще может находиться в буфере, и я не вижу ее.

Я знаю, что могу сбросить stdio, добавив в программу код флеша. Не делая этого, есть ли способ сказать GDB, чтобы очистить stdio от отлаживаемой программы после остановки GDB? Этот способ более дружелюбен при отладке программы.

Ответ 1

Многие недавние реализации UNIX stdio будут очищать все буферы, если вы вызываете fflush(NULL):

(gdb) call fflush(0)

Но обычно вам не нужно этого делать: если вы вызываете printf (а не fprintf), то идет stdout, который идет на ваш терминал, который обычно будет буферизироваться по строке. Поэтому, пока ваш printf напечатал новую строку, буфер был бы сброшен после возврата printf.

Ответ 2

GDB позволяет вызывать функции C непосредственно из командной строки. Таким образом, вы могли бы сделать

(gdb) call setbuf(stdout, NULL)

Теперь единственная проблема заключается в том, что я не знаю способа "получить" реальное значение stdout во время выполнения.

EDIT Это может помочь (от к документам):

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

Ответ 3

Если вы определяете функцию в своей программе:

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

Ответ 4

Вы можете использовать команду display, как в (gdb) display, подробности о которой можно найти здесь. Как только GDB встретит символ конца строки, такой как "\n", вывод будет отображен Вы можете выключить дисплей, используя undisplay.