From owner-freebsd-hackers Wed Sep 26 9:33:19 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from wall.polstra.com (wall-gw.polstra.com [206.213.73.130]) by hub.freebsd.org (Postfix) with ESMTP id 97E8E37B42C for ; Wed, 26 Sep 2001 09:33:14 -0700 (PDT) Received: from vashon.polstra.com (vashon.polstra.com [206.213.73.13]) by wall.polstra.com (8.11.3/8.11.3) with ESMTP id f8QGX7812327; Wed, 26 Sep 2001 09:33:07 -0700 (PDT) (envelope-from jdp@wall.polstra.com) Received: (from jdp@localhost) by vashon.polstra.com (8.11.6/8.11.0) id f8QGX7B02240; Wed, 26 Sep 2001 09:33:07 -0700 (PDT) (envelope-from jdp) Date: Wed, 26 Sep 2001 09:33:07 -0700 (PDT) Message-Id: <200109261633.f8QGX7B02240@vashon.polstra.com> To: hackers@freebsd.org From: John Polstra Cc: Nick.Barnes@pobox.com Subject: Re: distinguising read faults and write faults In-Reply-To: <52872.1001521231@thrush.ravenbrook.com> References: <52872.1001521231@thrush.ravenbrook.com> Organization: Polstra & Co., Seattle, WA Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG In article <52872.1001521231@thrush.ravenbrook.com>, Nick Barnes wrote: > I am in the process of porting an incremental garbage collector to > FreeBSD on x86. This garbage collector uses read barriers and write > barriers for incrementality. The details are irrelevant; the key part > is that I want to protect parts of memory and handle faults on the > protected pages. > > On FreeBSD, I will be using mmap(MAP_ANON) to obtain memory, and > mprotect() to raise the barriers, with a signal handler to handle > barrier hits. The garbage collector in Modula-3 is constructed this way exactly. It works pretty well. > I have worked out that I need to handle SIGBUS (not SIGSEGV, which > surprised me), and that ucontext->mcontext.mc_trapno will be 12 > (T_PAGEFLT, not T_PROTFLT, which surprised me). However, I don't see > any way of distinguishing between read faults and write faults. This > information doesn't appear to be anywhere in the ucontext or the > siginfo. > > Is there any way of distingushing read faults from write faults (other > than by decoding the instruction at mc_eip)? I don't know of a way. I notice that the collector in Modula-3 protects some regions as read-only and other regions as inaccessible (unreadable and unwritable). There is one thing you need to be aware of. You will need to wrap every system call which takes a pointer as an argument. If you pass a pointer to inaccessible memory to a system call, you don't get a signal. Instead, the call returns EFAULT. So you have to wrap every such system call and make sure its arguments have been made accessible before issuing the call. There is an example of this in the Modula-3 code (look for RTHeapDepC.c). It's a pain, because any little change in the prototype of a system call (e.g., addition of "const") breaks compilation of the corresponding wrapper. As far as I can tell, the whole EFAULT mess is a relic from the days before system calls became restartable in Unix. Today it would be possible to add a new signal SIGFAULT which could be caught to handle this case. Then the wrappers wouldn't be needed. It could still be backward compatible; an application which didn't install a SIGFAULT handler would get EFAULT returns in the traditional way. "One Of These Days" I'm going to add this to FreeBSD. John -- John Polstra jdp@polstra.com John D. Polstra & Co., Inc. Seattle, Washington USA "Disappointment is a good sign of basic intelligence." -- Chögyam Trungpa To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message