Вопрос
Прямо, когда я нахожусь в fflush (stdout), и я сломаю там в GDB, могу ли я узнать, что там в Stdout, прежде чем я на самом деле печатаю это?
Как я могу узнать, что в Stdout в любой момент времени?
Решение
Вы почти наверняка можете, но вы, вероятно, не должны. Стандарт требует только этого FILE
Быть типом, который полезен для реализации, чтобы идентифицировать открытый файл, и все, что необходимо для реализации семантики различных функций, которые работают на потоках.
Я обычно согласен с другими плакатами, которые fflush()
это надежный способ узнать, что вы на самом деле написали в файл.
Однако, если вы потеряли отслеживание того, какие части вашего кода могут писать в поток, то он иногда может быть полезен для наблюдения за потоком в действии и поймать его изменения.
На практике, FILE
Typedef для struct
Это объявлено вашим внедрением в заголовом файле stdio.h (часто называется struct _iobuf
). Хотя типичная реализация только слегка документирует своих членов, типичная реализация также реализует putchar()
И некоторые из его друзей как макросов, которые также встречаются в Stdio.h. Что, в сочетании с вероятной доступностью источников для библиотеки времени выполнения C любых инструментов, которые вы, вероятно, используете с GDB, получают все необходимую информацию под капотом.
Stdio.h предоставлено в Mingw GCC 3.4.5. FILE
следующее:
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
// oversimplify declaration of _iob[] here for clarity:
extern FILE _iob[FOPEN_MAX]; /* An array of FILE imported from DLL. */
//...
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define stdin (&_iob[STDIN_FILENO])
#define stdout (&_iob[STDOUT_FILENO])
#define stderr (&_iob[STDERR_FILENO])
и реализация putchar()
В качестве встроенной функции используя преимущества расширения GCC к C:
__CRT_INLINE int __cdecl __MINGW_NOTHROW putchar(int __c)
{
return (--stdout->_cnt >= 0)
? (int) (unsigned char) (*stdout->_ptr++ = (char)__c)
: _flsbuf (__c, stdout);}
Из этого вы можете сказать, что конец буфера указан на члена _ptr
, и вывод, что единственный другой char *
в struct _iobuf
(_base
) указывает на начало буфера. Член _cnt
Ясно, что подсчет неиспользуемых персонажей, оставшихся в буфере. Функция _flsbuf()
Должен принять первый персонаж, который не поместил и поместил его в начале буфера после того, как он написал текущий контент буфера в файл и восстановил _cnt
поле.
Итак, если вы смотрите stdout->_base
и BUFSIZ - stdout->_cnt
Вы бы, для этой реализации, имеют отображение того, сколько и что в текущем буфере.
Другие советы
Если вы выделите буфер самостоятельно и передайте его setvbuf., Я полагаю, вы можете получить доступ к нему перед тем, как вы начнутся с.
РЕДАКТИРОВАТЬ: Ваш комментарий сделал ваше намерение более понятно, но что вы хотите, не будет легко:
- Настройте свой собственный буфер, как описано выше,
- Установить A. Читать точку наблюдения на
stdout
, - Смотрите свою программу медленно до ползания.
С тех пор, gdb
остановится каждый раз что-либо доступ stdout
, и вы можете проверить свой буфер для изменений, странный выход и т. Д.
Тем не менее, это не идеальное решение вообще. Гораздо лучший подход будет использовать функцию выхода с включенной в систему везде в вашем коде.
Я думаю, что лучше прошить stdout
, что означает, что вы видите содержимое на экране или в файле (если stdout
перенаправляется).
Используйте «SetBuf ()» и держите ручку в буфер, который вы можете заглянуть. К сожалению, я не знаю топ, как найти смещение и длину недоверенных данных.