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.
If you do really need to use mmap, you could install a signal handler for SIGBUS. Its task should basically be to:
- Set a global (or thread-local, if your program is multi-threaded) flag that a
SIGBUS occurred, so the faulting code can be aware.
- 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.
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.
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.