Вопрос

Прямо, когда я нахожусь в 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., Я полагаю, вы можете получить доступ к нему перед тем, как вы начнутся с.

РЕДАКТИРОВАТЬ: Ваш комментарий сделал ваше намерение более понятно, но что вы хотите, не будет легко:

  1. Настройте свой собственный буфер, как описано выше,
  2. Установить A. Читать точку наблюдения на stdout,
  3. Смотрите свою программу медленно до ползания.

С тех пор, gdb остановится каждый раз что-либо доступ stdout, и вы можете проверить свой буфер для изменений, странный выход и т. Д.

Тем не менее, это не идеальное решение вообще. Гораздо лучший подход будет использовать функцию выхода с включенной в систему везде в вашем коде.

Я думаю, что лучше прошить stdout, что означает, что вы видите содержимое на экране или в файле (если stdout перенаправляется).

Используйте «SetBuf ()» и держите ручку в буфер, который вы можете заглянуть. К сожалению, я не знаю топ, как найти смещение и длину недоверенных данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top