生成读取错误

Generate a read error

提问人:William Pursell 提问时间:6/27/2012 更新时间:5/30/2013 访问量:2070

问:

通过写入 在测试套件中生成写入错误很简单。有没有一个好的技术来生成读取错误?我目前正在使用 LD_PRELOAD 进行覆盖,但这似乎太复杂且不可移植(并不是说 /dev/full 是可移植的....../dev/fullread

UNIX 测试

评论

0赞 David R Tribble 6/28/2012
只是一个想法,但是从 perms 设置为 000 的文件中读取呢?
0赞 William Pursell 6/28/2012
@Loadmaster 这将导致错误而不是错误。openread
0赞 William Pursell 6/28/2012
@jpe 我不太在乎错误是什么;我想成功打开文件,但出现读取错误。我不想简单地调用使用无效指针调用读取的函数,而是希望在触发读取错误的条件下完整运行程序。使用无效指针的简单单元测试不会在实际条件下测试程序。
1赞 Gilles 'SO- stop being evil' 5/30/2013
关于服务器故障以及 Unix 和 Linux 的相同问题。

答:

2赞 Norman Gray 6/28/2012 #1

根据 (OS X) read(2) 手册页,如果 “[a]n attempt to read a directory” ,read(2) 将生成错误。因此,您可以打开(2)一个目录(确保 prot 不允许写入,否则会抛出错误),然后尝试从中读取。这看起来像是那里列出的唯一错误,它可能发生在“正常”情况下(即没有做一些事情,比如故意破坏 FILE* 结构)。

我假设你说的是 C 或类似的东西中的 read(2) 错误,但即使在更高级的语言中,你也可以打开一个目录并尝试从中读取(尽管我只是用 Python 尝试过,它太聪明了,不能让你打开目录......

1赞 Suzuki Poulose 6/28/2012 #2

您也可以将非法指针作为缓冲区传递给读取,这将返回 -EFAULT。 像这样:

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

谢谢 铃木

评论

0赞 jpe 6/28/2012
这不会生成读取错误 (EINVAL) ,但在读取期间,缓冲区位于可访问地址空间 (EFAULT) 之外。但根据人 2 的阅读,应该可以通过稍作修改到达 EINVAL。但问题的重点似乎是“如何在不修改代码的情况下获得 EINVAL,但生成一个可以模拟所有有趣故障情况的包装器”。
0赞 William Pursell 6/28/2012
事实上,代码不应该被修改,进程必须成功地打开一个文件,执行多个 I/O 操作(读取和写入),但随后应该进行一些后续的读取操作以失败。这可以通过重写 read 并实现一个简单的计数器来实现,以便第 N 次读取操作失败,但最好从类似于 shell 脚本中执行一些操作: .在类似条件下获取写入错误的方法会很好,因为写入 /dev/full 在第一次写入时失败。kill -STOP $pid; chmod 000 file; kill -CONT $pid
7赞 rubasov 7/6/2012 #3

除了从目录读取(如前面的答案中提到的)之外,您还可以尝试读取以获得错误(这应该会在 Linux 上获得错误)。有关说明,请参阅:https://unix.stackexchange.com/a/6302/proc/self/memEIO

评论

0赞 Gilles 'SO- stop being evil' 5/30/2013
不错的技巧,但要注意,只有从文件开头阅读时才有好处。如果程序首先搜索,它可能会意外地进入映射区域。/proc/self/mem
0赞 Christian Hujer 4/25/2022
使用 bash shell 将 /proc/self/mem 映射到 stdin 时,这似乎不会产生错误。使用 fopen() 打开 /proc/self/mem 时,它会生成错误。由于以下两个原因,这是不可移植的:在没有 /proc 文件系统的系统上,这将失败。在映射了 NULL 的系统(例如 Amiga OS)上,这将改为成功读取(直到命中未映射的内存)。不过,这可能是最方便的解决方案。(点赞)
4赞 Gilles 'SO- stop being evil' 5/30/2013 #4

适用于所有主要 unice 的方法是实现一个小型 FUSE 文件系统。EIO 是用户空间文件系统驱动程序做错事时的默认错误代码,因此很容易实现。PerlPython 绑定都附带了示例,您可以快速编写一个文件系统,该文件系统主要镜像现有文件,但在精心选择的位置注入 EIO。

有一个现有的这样的文件系统:petardfs文章),我不知道它开箱即用的效果如何。