Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Sep 2001 09:33:07 -0700 (PDT)
From:      John Polstra <jdp@polstra.com>
To:        hackers@freebsd.org
Cc:        Nick.Barnes@pobox.com
Subject:   Re: distinguising read faults and write faults
Message-ID:  <200109261633.f8QGX7B02240@vashon.polstra.com>
In-Reply-To: <52872.1001521231@thrush.ravenbrook.com>
References:  <52872.1001521231@thrush.ravenbrook.com>

next in thread | previous in thread | raw e-mail | index | archive | help
In article <52872.1001521231@thrush.ravenbrook.com>,
Nick Barnes  <Nick.Barnes@pobox.com> 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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200109261633.f8QGX7B02240>