我正在对可以卸载的文件执行mmap()(该文件位于用户可以随时移除的USB设备上),以及我的应用程序崩溃,如果文件被卸载,然后我尝试访问缓冲区中的任何元素。在卸载的文件上执行mmap()后避免崩溃
对此的任何解决方案?
我正在对可以卸载的文件执行mmap()(该文件位于用户可以随时移除的USB设备上),以及我的应用程序崩溃,如果文件被卸载,然后我尝试访问缓冲区中的任何元素。在卸载的文件上执行mmap()后避免崩溃
对此的任何解决方案?
请勿访问不可用的文件。检查文件是否仍然存在,或使用无法卸载的文件。
最简单的事情就是设置一个信号处理程序,用于检查对应于mmap
编址的存储器位置的访问。
你会使用sigaction
形式的信号处理程序,而不是简单的signal
处理器为sigaction
处理对应于信号的地址struct __siginfo *
参数接收信息。可以检查它是否位于mmap
ed文件的地址范围内。
mmap
当你不想处理缓冲区读/写数据的复杂性,但是由于出错而只能得到一种形式的错误(信号)时,它非常棒。通过read
/write
机制,您可以获得errno
并确定发生了什么。在这种情况下,它非常适合开发者。
要跳转到一个位置接收到信号后,那么你就需要利用setjmp
和longjmp
/siglongjmp
的 - 看到this question
首先是一些使用此,我想说这应该作为一个很好的参数不要使用mmap
不必要地作为“优化读取”或类似。除了设备移除之外,其他进程的文件截断等问题可能会导致访问错误SIGBUS
。
如果确实需要使用mmap
,则可以安装SIGBUS
的信号处理程序。它的任务应该主要是为了:
SIGBUS
发生了全球性(或线程本地,如果你的程序是多线程)标志,所以出错的代码可以做到心中有数。mmap
与MAP_FIXED
可以在错误页面顶部映射一个新的匿名页面。可选填写访问地图的代码将被识别为错误的数据;这可能会导致第1步不必要。另一种方法是设置一个全球性的(或者线程本地)访问地图前jmp_buf
,并且已经在信号处理程序只需调用longjmp
。
注意,无论是mmap
也不longjmp
是异步信号安全的,但有问题的SIGBUS
不是异步信号(尽管它应该算得上一个,如果断裂访问发生在非异步信号安全库内功能如sscanf
)。只要它是你自己的代码,而不是库函数,访问地图,你就应该安全。并且mmap
在大多数/所有现实世界的实现中都是异步信号安全的,因此即使它在形式上不正确,您也应该在实践中使用第一种解决方案。
会这样说:对于'mmap'来说更多的不是满足眼睛 - 因为错误处理比传统的I/O要复杂得多。这不一定是一个理由_against using_'mmap' ...只是意识到你召唤的精神;-) –
并确保他们不会飞出你的鼻子.. :-) –
您可以通过使用http://linux.die.net/man/7/inotify来获得关于文件,目录中的任何更改的通知。 你可以考虑使用IN_DELETE。
这些通知将是立即因为OP试图遏制的页面错误?如果没有,请不要打扰。 –
看来你必须调用'read()'来查明是否有任何改变,但是在'read()'没有返回任何兴趣和下面的内存访问之间可能发生改变。这是一个竞赛条件。此外,事件队列可能会溢出。所以,这不是一个解决方案。 –
由于可能的竞赛条件,我不认为这是非常有用的。围绕访问映射区域的代码期望并捕获“SIGBUS”会有帮助吗?或者类似的东西? –
编号'SIGBUS'不一定是可恢复的,尽管一些实现在从处理程序返回后重试错误指令。 –
@SimonRichter你不需要重试错误指令,你只需要确定你不能继续读/写,之后你停止尝试访问区域并返回给调用者一些错误指示。也许'setjmp()'/'longjmp()'可以避免重新执行错误指令。 –