在卸载的文件上执行mmap()后避免崩溃 [英] Avoid crash after doing mmap() on a file that is unmounted

查看:130
本文介绍了在卸载的文件上执行mmap()后避免崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm doing mmap() on a file that can be unmounted ( the file is located on an USB device which the user can remove at any time ), and my application crashes if the file is unmounted and then i try to access any element in the buffer.

有什么解决办法吗?

推荐答案

首先,我想说这应该作为一个很好的论据,不要使用 mmap,不必要地将其用作优化阅读"或类似内容.除了删除设备之外,其他进程诸如文件截断之类的问题也会导致对SIGBUS的访问出错.

First of all, I would like to say this should serve as a good argument not to use mmap unnecessarily as an "optimized read" or similar. Aside from device removal, issues like file truncation by other processes can cause accesses to fault with SIGBUS.

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

If you do really need to use mmap, you could install a signal handler for SIGBUS. Its task should basically be to:

  1. 设置一个全局的(或线程本地的,如果您的程序是多线程的)标志,该​​标志表示发生了SIGBUS,因此可以识别出错误的代码.
  2. 使用MAP_FIXED调用mmap将新的匿名页面映射到故障页面的上方. (可选)用访问地图的代码将其识别为错误的数据填充数据;这可能使步骤1变得不必要.
  1. Set a global (or thread-local, if your program is multi-threaded) flag that a SIGBUS occurred, so the faulting code can be aware.
  2. Call mmap with MAP_FIXED to map a new anonymous page over top of the faulting page. Optionally fill it with data which will be recognized by the code accessing the map as erroneous; this could make step 1 unnecessary.

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

An alternative approach would be to set a global (or thread-local) jmp_buf before accessing the map, and have the signal handler simply call longjmp.

请注意,mmaplongjmp都不是异步信号安全的,但是所讨论的SIGBUS不是异步信号(尽管如果故障访问发生在非异步内部,则应该将其视为一个异步信号. -信号安全库函数,例如sscanf).只要是您自己的代码(而不是库函数)来访问地图,那么使用这两种方法都应该是安全的.而且mmap在大多数/所有实际实现中都是异步信号安全的,因此即使在形式上不正确,您也可以在实践中使用第一个解决方案.

Note that neither mmap nor longjmp is async-signal-safe, but the SIGBUS in question is not an asynchronous signal (although it should perhaps be considered one if the faulting access happened inside a non-async-signal-safe library function such as sscanf). As long as it's your own code, and not library functions, accessing the map, you should be safe with either. And mmap is async-signal-safe in most/all real-world implementations, so you should be okay with the first solution in practice even if it's not formally correct.

这篇关于在卸载的文件上执行mmap()后避免崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆