Subject: Re: SIGTRAP for traced processes and COMPAT_MACH
To: Emmanuel Dreyfus <manu@NetBSD.org>
From: Matthew Orgass <firstname.lastname@example.org>
Date: 11/30/2003 04:14:02
On 2003-11-30 manu@NetBSD.org wrote:
> psignal -> psignal1 -> kpsignal2 -> ksiginfo_put
> kpsignal -> kpsignal1 -> kpsignal2 -> ksiginfo_put
> trapsignal -> kpsignal -> kpsignal1 -> kpsignal2 -> ksiginfo_put
kpsignal2 is also called from a few other places in kern_sig.c (which
is why intercepting psignal/kpsignal is not a good idea).
> Another fix is to allow an emulation hook on kpsignal2. The Darwin
> version of kpsignal2 would raise a Mach exception or call the native
> kpsignal2, exactly like it is already done for trapsignal. There is just
> one problem: darwin_trapsignal would call the native trapsignal, and
> trapsignal can call kpsendsig2, so darwin_trapsignal should take care to
> avoid the situation where two Mach exceptions are raised for the same
> exception: one by darwin_trapsignal, and one by darwin_kpsignal2.
Why would darwin_trapsignal call trapsignal if a mach exception is
raised? I thought the point of this is to not do so.
> Or (third fix possible), add a call to an emulation-hooked test function
> in both trapsignal and kpsignal2 and inhibit the signal there. It would
> look like this:
> if (p->p_emul->e_checksignal && (*p->p_emul->e_checksignal)(p, ksi))
> darwin_checksignal would try to raise a Mach exception and would return
> a non zero value if it failed to do so.
> This seems the best way to me. This is clean code, and for native
> processes, this just costs a check that p->p_emul->e_checksignal == NULL
Since kpsignal2 is static this is better there, but I don't see how it
would benefit trapsignal.
Also, should kevents be sent if a Mach exception is raised?
I don't think the performance impact of two loads and a test should have
any bearing on how this should be done. Compat code alredy has an effect
on MI code; if it is desireable to have a "NetBSD only" system, then make
it possible to define out *all* of the MI compat code.
Performance of the compatability code should also be considered. If the
code will be duplicating the signal code, then sendsig should be used.
But it doesn't sound like this should be the case; it sounds like this
should be a much shorter code path. If it is actually used for the
eqivalent of SIGIO, then it could have a real impact on compatability
performance, as opposed to minimal impact on native code.
However, looking at the documentation I can find:
this might not actually be the case. At least thread_get_exception_ports
does not seem to have any normal signal exceptions and I don't see
anything else that would seem to apply.
Looking quickly at the darwin kernel code (which I can now find thanks
to the above link identifying the kernel as being called xnu, for reasons
I can not guess)... reveals only that signals are not done the same place
in darwin :(. Since I don't have a local copy I can't grep the code.
So: does this really need to apply generally to all signals? If not,
the origional idea of just calling e_trapsignal for SIGTRAP would seem to
make the most sense.