2010-10-29 94 views
2

正当我在fflush(stdout)并在GDB中打开时,我可以知道标准输出中有什么在我实际打印之前?fflush(stdout)in c

我怎么知道标准输出中有什么时间点?

+0

我想我没有解释得很好。基本上,当我的程序结束并刷新标准输出时,我看到了怪异的o/p。这就是为什么我想要监控标准输出所有时间,看看什么是什么时候和谁被写入。 – hari 2010-10-29 21:32:24

+0

如果使用'setvbuf(stdout,NULL,_IONBF,0)'切换到无缓冲输出,会发生什么? – 2010-10-29 21:55:09

回答

1

你几乎可以肯定,但你可能不应该。该标准仅要求FILE是一种对实现来说很有用的类型,以识别打开的文件以及实现操作在流上的各种函数的语义所需的任何状态。

我通常会同意其他海报fflush()是一种可靠的方式来知道你实际写了什么文件。但是,如果您忘记了代码的哪些部分可能正在写入流中,那么偶尔可能有助于观察流中的流并捕获流的变化。

实际上,FILE是一个struct的typedef,由您的实现在头文件stdio.h中声明(通常名为struct _iobuf)。尽管典型的实现只是轻描述其成员,但一个典型的实现也实现了putchar()及其一些朋友作为也在stdio.h中找到的宏。那么,再加上你可能会用到gdb的任何工具链的C运行时库可能的源代码,就可以获得你需要的全部信息。

在MinGW GCC 3.4中提供的stdio.h。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,并推断struct _iobuf_base)中唯一的其他char *指向缓冲区的开始。成员_cnt显然是缓冲区中剩余未使用字符的计数。函数_flsbuf()必须将第一个不合适的字符放到缓冲区的起始位置,然后将当前缓冲区内容写入文件并恢复_cnt字段。

因此,如果您观看stdout->_baseBUFSIZ - stdout->_cnt,您可以在此实现中显示当前缓冲区中的内容和内容。

1

我认为最好冲洗stdout,这意味着基本上你看到屏幕上或文件中的内容(如果stdout被重定向)。

0

使用“setbuf()”,并保留缓冲区的句柄,您可以查看。不幸的是,我不知道如何找到未刷新数据的偏移和长度。

2

如果你自己分配一个缓冲区并将它传递给setvbuf,我想你可以在flush之前访问它,因为它是你的开始。

编辑:您的评论使你的意图更加清晰,但你想将是不容易的:

  1. 如上所述设置自己的缓冲区,
  2. 坐落在stdout一个read watchpoint
  3. 观看您的节目缓慢爬行。

从此,gdb每次都会什么访问stdout打破,你可以检查缓冲区更改,怪异输出等

也就是说,这不是一个理想的解决方案在所有。更好的方法是在代码中的任何地方都使用启用日志功能的输出函数。

+0

一个问题:不能保证'setvbuf'甚至会使用你给它的缓冲区。如果它大于现有的内部缓冲区,它可能会选择使用它,或者始终忽略它。 – 2011-06-08 16:31:09