флеш (стандартный) в с - PullRequest
       42

флеш (стандартный) в с

2 голосов
/ 30 октября 2010

Правильно, когда я нахожусь на fflush (stdout), и я ломаюсь там в GDB, могу ли я узнать, что есть в stdout, прежде чем я действительно напечатаю его?

Как я могу узнать, что есть в stdout в любой момент времени?

Ответы [ 4 ]

2 голосов
/ 30 октября 2010

Если вы выделите буфер самостоятельно и передадите его в setvbuf , я полагаю, вы можете получить к нему доступ до сброса, поскольку он ваш с самого начала.

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

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

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

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

1 голос
/ 30 октября 2010

Вы почти наверняка можете, но, вероятно, не должны.Стандарт требует только, чтобы 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, для этой реализации вы увидите, сколько и что находится в текущем буфере.

1 голос
/ 30 октября 2010

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

0 голосов
/ 30 октября 2010

используйте "setbuf ()" и держите дескриптор буфера, который вы можете посмотреть.К сожалению, я не знаю, как найти смещение и длину непроверенных данных.

...