On Tue, Aug 25, 1998 at 01:45:12AM +0100, Jamie Lokier wrote:> Will I don't agree with the feature either, all we're talking about is> adding one line to the page fault handler: send_sig(SIGSEGV). Nothing> else needs to change, does it?

I just changed my mind.

I bet no applications at all currently check for EFAULT from systemcalls, unless they're really weird and are doing it to behave _as if_they'd received SIGSEGV. Actually I bet they don't bother because everysyscall would need to be wrapped. I'm theorising that this could screwup Wine in some unusual but valid cases.

To make matters worse, if they do this by calling the signal handlerdirectly, the faulting address isn't available. If they do kill(getpid(),SIGSEGV), a fault may have happened in the mean time so thefaulting address may be wrong or lost. In the latter case, as luckwould have it, probably the operations retry until the right address isfound. But it is a matter of luck, and anything that tried to countfaults could get it wrong in these rare cases.

So...

- EFAULT alone is an anachronism. - Only a few applications care whether SIGSEGV is raised or not. - Some emulators and user-space page management depend on SIGSEGV for page faults, and will behave incorrectly when it is not raised in syscalls. - There is no correct workaround other than the kernel raising SIGSEGV.

I propose EFAULT should be retained, but faulting syscalls should _also_raise SIGSEGV.

Addendum for a related problem: Consider when a syscall, interruptetc. (whatever) combination manage to raise more than one signal _at thesame time_, of which one is SIGSEGV due to a page fault. Assume theprogram is using user-space page management for something.

A handler for one of the other signals is called first. The handler mayitself fault, causing a SIGSEGV if it is not blocked. Or perhapsstoring the context on the stack might fault. A nested call to the SEGVhandler handles the inner fault. The other handler returns, then acontext the SIGSEGV handler is called for the original fault. Now, thepage fault address from %cr2 (or non-Intel equivalent) is stored in thecontext passed to the handler. But it is wrong by now! It is theaddress of the inner fault, which has already been handled.

Ho hum.

Perhaps a VM extension could be written, whereby page faults send aqueued real-time signal along with the faulting address, and maybe someinformation to identify the faulting region too. That would workproperly because the address can be queued at the time of the fault.