mmap and SIGBUS
Andrew V. Samoilov
kai at cmail.ru
Fri Sep 21 12:06:34 UTC 2001
Hi!
Here is a parts of my and Jamie Lokier <lk at tantalophile.demon.co.uk> letters about mmap.
We discussed this at Linux Kernel mailing list, but it seems it is standart behaviour
of Unices kernel's.
Andrew V. Samoilov wrote:
> I have bad CD-R with a some number of unreadable files.
>
> User-space program use mmap system call and it returns ok but any
> attempt to access a memory pointed by this system call finishes
> with SIGBUS. So Midnight Commander internal file viewer faults.
You can get the same problem even without read errors with some
configurations of NFS. (root mmaps a file owned by someone else, but
cannot read the file due to `root_squash' on server).
It's not an error, it's standard behaviour.
> Is there any way to detect such problem in user-space without signal
> handlers ?
I don't think there is any way without a signal handler.
It is possible to do something useful with a signal handler sometimes.
For example, you can mmap() a zero page into the offending page once
you've got the fault address, or read() a zero page if you did
MAP_PRIVATE (this produces fewer VMAs), set a flag, and let the program
continue until it checks the flag and aborts the parsing or whatever
operation it's doing.
Unfortunately I don't think the signal handler's si_errno is set
properly to indicate the error. So another thing to try is read() of
the offending page, to get a useful error code. (And if the read
succeeds, that's ok because you did it at the correct address so the
program can proceed anyway).
Fwiw, unfortunately not all versions of the kernel, or all
architectures, set si_addr properly for SIGBUS.
It is possible to do something useful with a signal handler sometimes.
For example, you can mmap() a zero page into the offending page once
you've got the fault address, or read() a zero page if you did
MAP_PRIVATE (this produces fewer VMAs), set a flag, and let the program
continue until it checks the flag and aborts the parsing or whatever
operation it's doing.
> So, I must read all of the mapped area and even this
> does not saves me of faulting next time if somebody
> change file permission. Does I understand this situation right?
If you use MAP_PRIVATE, then after your process modifies the mappedpage, you have the data
for sure. This includes calling read() over apage that raises a SIGBUS -- the page is "modified"
by this operation,although the contents should hopefully be the correct file contents if
read() succeeds. Any subsequent change to the file, including permission changes and
data changes, won't affect the data you have in memory. If you do not modify the pages
(and usually, for efficiency, you wouldn't), then yes a change in file permissions can mean
you can read data one second and will get a SIGBUS later. You're not guaranteed to get a SIGBUS,
but you might get one -- it depends on whether the OS decides to reclaim the page's memory
temporarily in between.
If you want to do something like an Editor's "Load File" operation, then
you need to read the whole file. Either call read(), or call mmap() andthen modify every page
by reading one byte from each page and writingthe same value back to the same place.
read() is probably quicker, but I've never checked.
-- Jamie
____________________________________________
Играй в шахматы в Интернет на InstantChess.com!
Play chess on InstantChess.com !
www.instantchess.com
More information about the mc-devel
mailing list