繁体   English   中英

在卸载的文件上执行mmap()后避免崩溃

[英]Avoid crash after doing mmap() on a file that is unmounted

我正在对可以卸载的文件执行mmap()(该文件位于用户可以随时删除的USB设备上),如果文件已卸载,我的应用程序崩溃然后我尝试访问任何元素在缓冲区。

对此有何解决方案?

首先,我想说这应该作为一个很好的论据, 不要不必要地使用 mmap作为“优化读取”或类似的。 除了设备删除之外,其他进程的文件截断等问题都可能导致访问SIGBUS错误。

如果确实需要使用mmap ,可以为SIGBUS安装信号处理程序。 它的任务基本上应该是:

  1. 设置一个全局(或线程本地,如果你的程序是多线程的)标志SIGBUS发生,所以故障代码可以知道。
  2. 使用MAP_FIXED调用mmap以在错误页面的顶部映射新的匿名页面。 可选地填充数据,该数据将被访问地图的代码识别为错误的; 这可能使步骤1变得不必要。

另一种方法是在访问映射之前设置全局(或线程局部) jmp_buf ,并让信号处理程序简单地调用longjmp

请注意, mmaplongjmp都不是异步信号安全的,但所讨论的SIGBUS不是异步信号(尽管如果故障访问发生在非同步信号安全库函数内,例如sscanf它应该被认为是一个) )。 只要它是你自己的代码,而不是库函数,访问地图,你应该是安全的。 并且mmap在大多数/所有实际实现中都是异步信号安全的,所以即使它不是正式的,你也应该在实践中使用第一个解决方案。

最简单的方法是设置一个信号处理程序,检查对与mmap ed地址对应的内存位置的访问。

您将使用信号处理程序的sigaction形式,而不是简单的signal处理程序,因为sigaction处理程序在struct __siginfo *参数中接收与信号地址对应的信息。 可以检查它是否在mmap ed文件的地址范围内。

当你不想处理缓冲区读/写数据的复杂性时, mmap很棒,但是你只会因为出错而得到一种形式的错误(信号)。 使用read / write机制,您可以获取errno并确定发生了什么。 在这种情况下,它是开发人员的选择。

要在收到信号后跳转到某个位置,那么您将需要使用setjmplongjmp / siglongjmp - 请参阅此问题中的一些用法

不要访问不可用的文件。 检查文件是否仍然存在,或使用无法卸载的文件。

您可以使用http://linux.die.net/man/7/inotify获取有关文件,目录的任何更改的通知。 你可以考虑使用IN_DELETE。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM