2012-06-27 84 views
6

通過寫入/dev/full,在測試套件中生成寫入錯誤很簡單。有沒有一種很好的技術來產生讀取錯誤?我目前使用LD_PRELOAD覆蓋01​​,但這看起來太複雜和不可移植(不是/ dev/full是便攜式的...)。生成讀取錯誤

+0

只是一個想法,但如何從一個文件讀取設置爲000的燙金? –

+0

@Loadmaster這將導致「open」錯誤而不是「read」錯誤。 –

+0

您是否在EINVAL之後? – jpe

回答

5

除了從目錄中讀取(如在前面的回答中提到),你可以嘗試讀取/proc/self/mem得到一個錯誤(這應該讓你在Linux上的EIO )。有關說明,請參閱:https://unix.stackexchange.com/a/6302

+0

不錯的訣竅,但要注意'/ proc/self/mem'只有在你從文件的開頭讀取時纔有用。如果程序首先尋找,它可能會意外地在映射區域中結束。 – Gilles

2

根據(OS X)read(2)聯機幫助頁,如果「嘗試讀取目錄」,則read(2)將生成錯誤。因此,你可以打開(2)一個目錄(確保prot不允許寫入,否則會拋出錯誤),然後嘗試讀取它。這看起來像在那裏列出的唯一的錯誤,可能發生在'正常'的情況下(即沒有像故意破壞FILE *結構一樣)。我假設你正在討論在C或類似的東西中讀取(2)錯誤,但即使是在更高級別的語言中,你也許能夠打開一個目錄並嘗試讀取它(儘管我只是用Python試了一下,它太聰明瞭,不能讓你打開目錄...)

1

你也可以通過一個非法的指針作爲緩衝區來讀取,這將返回一個-EFAULT。 喜歡的東西:

read(fd, (char *)0, cout); 

感謝 鈴木

+0

這不會生成讀取錯誤(EINVAL),但在讀取期間緩衝區位於可訪問地址空間(EFAULT)之外。但根據man 2的說法,應該可以稍微修改一下EINVAL。但問題的關鍵似乎是「如何在不修改代碼的情況下進入EINVAL,而是生成一個可模擬所有有趣故障情況的包裝器」。 – jpe

+0

事實上,代碼不應該被修改,並且進程必須成功打開一個文件,執行多個I/O操作(包括讀取和寫入),但是後續的一些讀取操作應該失敗。這可以通過覆蓋讀取和實現一個簡單的計數器來實現,以便第N次讀取操作失敗,但是從類似於以下腳本的shell腳本中執行某些操作會很好:'kill -STOP $ pid; chmod 000文件;殺-CONT $ pid'。在類似的條件下獲得寫入錯誤的方法會很好,因爲在第一次寫入時寫入/ dev/full失敗。 –

4

適用於所有主要單位的方法是實施小型文件系統FUSE。當用戶空間文件系統驅動程序出錯時,EIO是默認錯誤代碼,因此很容易實現。 PerlPython綁定都帶有示例以便開始使用,您可以快速編寫一個主要反映現有文件但在精心挑選的地方注入EIO的文件系統。

有一個現有的這樣的文件系統:petardfsarticle),我不知道它是如何工作的。

+0

哦,+1:petardfs顯然是正確的事情。 –