gpt4 book ai didi

c - 真的不检查close()的返回值: how serious,吗?

转载 作者:IT王子 更新时间:2023-10-29 00:18:26 25 4
gpt4 key购买 nike

Linux的“手动关闭”警告(SVr4、4.3BSD,POSIX.1-2001):

Not checking the return value of close() is a common but nevertheless serious programming error. It is quite possible that errors on a previous write(2) operation are first reported at the final close(). Not checking the return value when closing the file may lead to silent loss of data. This can especially be observed with NFS and with disk quota.



我可以相信这个错误很常见(至少在应用程序中;我不是内核黑客)。但是,今天或过去三十年中的任何时候,它有多严重?特别是:

是否有一个简单,可重现的示例,说明这种无声的数据丢失?即使是人为的人也喜欢在close()期间发送SIGKILL?

如果存在这样的例子,是否可以比仅仅处理数据丢失更优雅
printf("Sorry, dude, you lost some data.\n");

最佳答案

[H]ow serious is it, today or at any point in the past three decades?



典型应用程序处理数据。他们消耗一些输入,并产生结果。因此,在两种常见情况下, close()可能会返回错误:关闭输入(只读?)文件时,以及关闭刚刚生成或修改的文件时。
close()返回错误的已知情况特定于将数据写入/刷新到永久存储中。特别是,在实际写入永久存储之前,操作系统通常先在本地缓存数据(在 close()fsync()fdatasync()处);这在远程文件系统中非常常见,这是手册页中提到NFS的原因。

关闭只读输入文件时,我从未遇到错误。我可以想到的是,使用任何常见文件系统在现实生活中可能发生的所有情况都是发生灾难性故障的情况,例如内核数据结构损坏。如果发生这种情况,我认为 close()错误不可能是出现严重错误的唯一迹象。

当在远程文件系统上写入文件时,如果本地网络容易出现故障或只是丢弃大量数据包,则 close() -time错误非常普遍。作为最终用户,我希望我的应用程序告诉我在写入文件时是否出错。通常,与远程文件系统的连接会完全断开,并且向新文件写入失败的事实是向用户显示的第一个指标。

如果您不检查 close()返回值,该应用程序将对用户说谎。它将指示(如果没有错误消息,则缺少错误消息)表明文件已正确写入,而实际上并非如此,并且已告知应用程序;该应用程序只是忽略了指示。如果用户像我一样,他们会对应用程序感到非常不满意。

问题是,用户数据对您有多重要?当前大多数应用程序程序员根本不在乎。 Basile Starynkevitch(在对原始问题的评论中)是绝对正确的;大多数程序员都不愿意检查 close()错误。

我认为这种态度是应受谴责的。骑士无视用户数据。

但是,这很自然,因为用户没有明确指示哪个应用程序破坏了他们的数据。根据我的经验,最终用户最终会归咎于操作系统,硬件,开源或免费软件,或者是本地IT支持。因此,程序员不必担心社交或其他方面的压力。因为只有程序员才知道诸如此类的细节,而且大多数程序员都不在乎,所以没有改变现状的压力。

(我知道上面的内容会使很多程序员讨厌我的胆量,但至少我是诚实的。我指出诸如此类的典型 react 是,这种情况很少见,浪费资源来检查这一点。这可能是正确的。但是我愿意花更多的CPU周期,并向程序员支付更多的费用,这是否意味着我的机器实际上更可预测地工作,并告诉我是否它丢失了情节,而不是无声地破坏了我的数据。)

Is there a simple, reproducible example of such silent loss of data?



我知道三种方法:
  • 使用USB内存棒,然后在最终write()之后但在close()之前将其拔出。
    不幸的是,大多数USB内存棒的硬件都设计得无法幸免,因此您最终可能会弄脏USB内存棒。
    取决于文件系统,您的内核也可能会死机,因为大多数文件系统都是在假设这种情况永远不会发生的前提下编写的。
  • 设置NFS服务器,并通过使用iptables丢弃NFS服务器和客户端之间的所有数据包来模拟间歇性数据包丢弃。
    确切的方案取决于服务器和客户端,安装选项和使用的版本。但是,使用两个或三个虚拟机来建立测试台应该相对容易。
  • 使用自定义文件系统模拟close()时的写入错误。
    当前的内核不允许您强制卸载tmpfs或环回安装,而只能强制卸载NFS,否则可以通过在最终写入之后但在close()之前强制卸载文件系统来轻松模拟。 (如果该文件系统上有打开的文件,则当前内核只是拒绝该卸载。)
    对于应用程序测试,创建一个tmpfs的变体,如果文件模式表明它是可取的(例如,其他可写但不是其他可读性或其他可执行性,即close()),则在-??????-w-处返回错误,并且非常容易,并且安全的。它实际上并不会破坏数据,但是如果内核在关闭时间报告数据破坏(存在风险),它将使检查应用程序的行为变得容易。
  • 关于c - 真的不检查close()的返回值: how serious,吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19056309/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com