2014-01-30 46 views
3

爲教育目的,我試圖替換標準流stdout,stdin和stderr。我首先擡頭的流的數據類型,這是我追溯到具有以下成員的結構_IO_FILE(GDB p-型_IO_FILE):爲什麼stdout不能被替換?

type = struct _IO_FILE { 
    int _flags; 
    char *_IO_read_ptr; 
    char *_IO_read_end; 
    char *_IO_read_base; 
    char *_IO_write_base; 
    char *_IO_write_ptr; 
    char *_IO_write_end; 
    char *_IO_buf_base; 
    char *_IO_buf_end; 
    char *_IO_save_base; 
    char *_IO_backup_base; 
    char *_IO_save_end; 
    struct _IO_marker *_markers; 
    struct _IO_FILE *_chain; 
    int _fileno; 
    int _flags2; 
    __off_t _old_offset; 
    short unsigned int _cur_column; 
    signed char _vtable_offset; 
    char _shortbuf[1]; 
    _IO_lock_t *_lock; 
    __off64_t _offset; 
    void *__pad1; 
    void *__pad2; 
    void *__pad3; 
    void *__pad4; 
    size_t __pad5; 
    int _mode; 
    char _unused2[20]; 
} 

然後我試圖複製標準輸出指針的存儲器內容:

_IO_FILE f1 = {._flags = -72540028, ._offset = -1, ._old_offset = -1, ._fileno = 1, ._chain = stdin, ._lock = stdout->_lock, .__pad2 = stdout->__pad2 }; 
_IO_FILE *f2 = stdout; 
_IO_FILE *f3 = malloc(sizeof(_IO_FILE)); 
memcpy(f3, stdout, sizeof(_IO_FILE)); 

fprintf(&f1, "f1\n"); // doesn't work 
fprintf(f2, "f2\n"); // works 
fprintf(f3, "f3\n"); // doesn't work 

但是,只有指針分配不會崩潰。我通過gdb比較了內存​​內容,並且都共享相同的結構成員內容。

雖然這個問題很可能是平臺相關的:做fprintf和其他庫函數只是比較指向標準流的指針?

編輯:我懷疑,這是一個執行或平臺相關的問題,因爲所有的意見都表明,它是,我接受了這個答案,它表明了問題的一個可能原因。

edit2:縮小問題的範圍:我使用的版本是12.04的64位ubuntu和2.15的EGLIBC版本。

+5

這是*完全*實施依賴。爲了找出答案,你應該檢查你的實現的源代碼(這基本上是其他人爲了寫這個問題的答案而必須做的......) –

+1

@OliCharlesworth但有人可以通過說什麼是幫助選中並在哪裏搜索。和你一樣。這已經是答案。這不是結束的理由。 – Gangnus

+1

在linux設備上調查。管理停止分割。看起來stdout結構持有一個鎖。複製結構是不夠的。見第43行:http://searchcode.com/codesearch/view/18356174 – Corvusoft

回答

1

根據Corvus的評論,在Linus系統上,鎖與流關聯,因此複製FILE數據結構會干擾鎖語義。

(我認爲這個答案不能馬上接受,給烏鴉座的時間進入一個答案。)


舊假說:

我懷疑,在你的C實現的一個位置FILE對象被用作其含義的一部分。例如,它們可能有一個數組,並且指向數組的第一個元素的指針將從指向FILE對象的指針中減去以在數組中找到它的索引。然後將此索引用作系統調用中的文件編號,例如write

當您分配新空間時,它不在此數組中,並且指針算術給出錯誤的結果。

相關問題