[comp.os.mach] using Mach exceptions and Unix signals in the same task

kolodner@lcs.mit.edu (Elliot Kolodner) (01/30/91)

I have ported a program that makes extensive use of the Unix signal facility
to Mach.   Now I need to modify the program.  The modification requires the
use of Mach exceptions.  However, I'd like to change the program itself as
little as possible.  In particular, I prefer not to modify the signal
handlers.  Is there a way to catch the Mach exceptions that I require in an
exception handler, and pass the rest back to system to be redelivered to the
program as Unix signals, i.e. is there a way for some exceptional conditions
to be processed as Mach exceptions and others to be processed as Unix signals.

Elliot

Richard.Draves@CS.CMU.EDU (01/31/91)

> Excerpts from netnews.comp.os.mach: 30-Jan-91 using Mach exceptions and
> U.. Elliot Kolodner@lcs.mit. (616)

> I have ported a program that makes extensive use of the Unix signal
> facility
> to Mach.   Now I need to modify the program.  The modification requires
> the
> use of Mach exceptions.  However, I'd like to change the program itself
> as
> little as possible.  In particular, I prefer not to modify the signal
> handlers.  Is there a way to catch the Mach exceptions that I require in
> an
> exception handler, and pass the rest back to system to be redelivered to
> the
> program as Unix signals, i.e. is there a way for some exceptional
> conditions
> to be processed as Mach exceptions and others to be processed as Unix
> signals.

Let me first review how Mach handles exceptions.  Threads and tasks can
have exception ports.  New tasks inherit their exception port from their
parent.  New threads have a null exception port.  The kernel makes
exception_raise upcalls to exception ports.  When a thread takes an
exception (illegal instruction, touches bad memory, breakpoint, etc.)
the kernel first tries the thread's exception port, if present, and if
that fails then the thread's task's exception port, if present.  An
exception_raise upcall fails if the exception server returns a value
other than KERN_SUCCESS.  If no exception server takes responsibility
for an exception (no exception ports, or the servers returned
non-KERN_SUCCESS), then the kernel terminates the thread's task.

All exceptions go through this mechanism.  However, the default
exception server is a task inside the kernel that converts the
exceptions into Unix signals.  Normally threads have a null exception
port, and tasks have an exception port for this default service.  (In
Mach 3.0, the default exception service is the responsibility of the
Unix emulation and isn't in the kernel.)

There are several things you can do.  First, if you want some threads to
get signals and others to contact your exception service, you can
install your exception port in selected threads.  Second, you can
install your exception port in all threads, and have your exception
server examine the arguments to the exception_raise upcall and return
non-KERN_SUCCESS for those exceptions that should get turned into
signals.  The kernel will retry with the task's exception port, for the
default exception service.  Third, your exception server can forward the
exceptions it doesn't want to handle to the default exception service in
the kernel.  Your task would retrieve its original exception port, for
forwarding, and install its own exception port.  And of course there are
various combinations of these strategies.

Rich

af@spice.cs.cmu.edu (Alessandro Forin) (01/31/91)

Although I find the use of signals despicable.. yes you can do that.
All you need is to grab your old exception port and stash it away,
replace it with one of your own ports, stick a thread to listen to
that port.  When an exception message comes, either handle it yourself
or forward the exception message on to the old exception port.

For a practical example, look at what the Mach GDB does.  I presume
sources should be part of the distribution, if not there is a copy
on wb1.

BTW, the instructions for FTPing from CMU clearly indicate that we
run secure FTP daemons: you can only "cd" to the prescribed directories,
any attempt to move elsewhere (INCLUDING intermediate directories)
is prohibited.

Hope this helps,
sandro-