On Wednesday 10 December 2008 10:06, Carmelo AMOROSO wrote:
> Carmelo AMOROSO wrote:
> > Hi Khem,
> > I'm seeing similar problem on sh4-nptl as happened to you as you told me 
> > yesterday.. Something recently merged is causing issues.
> > I'm doing investigation and keep you all informed.
> > 
> > Further I'm just writing a detailed report on current status of merge, 
> > that I can say is almost complete (once figured out what is not
> > actually working ;-) ).
> > 
> > I'm currently 100% focused on uclibc.
> > 
> > Cheers,
> > Carmelo
> Khem,
> I think to have found what is causing problems on nptl branch
> (anyway I don't know why yet).
> 
> The cause is the change merged from trunk in the file
> libc/sysdeps/linux/common/bits/sigset.h (rev 24243)
> 
> that includes all changes occurred in the same file on trunk
> in rev 24183 / 24220 / 24221 by vda.
> 
> Please may you try on ARM reverting that file
> and see if it helps. On sh4-nptl it's working better now
> Below the boot log on my box... not more PANIC on INIT
> even if it's blocking on udev
> 
> This seems confirming my idea on signal handling changes.
> I'll try to merge on my private branch all changes that are already
> in the nptl-branch but thos on signal handling.

The change is that sigset_t is not 1024 bits, but 64 bits
on almost all architectures. Only MIPS has 128.

This affects sigaction and sigprocmask, but they already
are translating libc struct sigaction / sigset_t to kernel's.

With this change sigset_t actually should match kernel one,
albeit struct sigaction is still different a bit.

Anyway, the symptom of breakage would be, for example,
in libc/sysdeps/linux/arm/sigaction.c:


int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction 
*oact)
{
        int result;
        struct kernel_sigaction kact, koact;
        enum {
                SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask)
                                ? sizeof(kact.sa_mask) : sizeof(act->sa_mask)
        };


*** first thing to check is whether sizeof(kact.sa_mask) == 
sizeof(act->sa_mask).
I tried to make it work even if it does not, but it's always better if they 
match.
add line
struct BUG { int bug[sizeof(kact.sa_mask) == sizeof(act->sa_mask) ? 1 : -1]; };
and if compile fails, sizeof's are not ==.
Let me know that.


        if (act) {
                kact.k_sa_handler = act->sa_handler;
                memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE);
                kact.sa_flags = act->sa_flags;
# ifdef HAVE_SA_RESTORER
                if (kact.sa_flags & SA_RESTORER) {
                        kact.sa_restorer = act->sa_restorer;
                } else {
                        kact.sa_restorer = choose_restorer (kact.sa_flags);
                        kact.sa_flags |= SA_RESTORER;
                }
# endif
        }



*** next:

        /* NB: kernel (as of 2.6.25) will return EINVAL
         * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
        result = __syscall_rt_sigaction(sig,
                        act ? __ptrvalue (&kact) : NULL,
                        oact ? __ptrvalue (&koact) : NULL,
                        sizeof(kact.sa_mask));

Basically, if it throws EINVAL, always, then sizeof(kact.sa_mask) is botched.
(Kernel simply compares it with constant, it must be correct to work,
no "greater or equal" slack there).
I think adding if (errno == EINVAL) write(2, "EINVAL!\n", 8);
will tell you whether it happens.


sigprocmask is simpler:

int sigprocmask(int how, const sigset_t * set, sigset_t * oldset)
{
        if (set &&
...
                ) {
                __set_errno(EINVAL);
                return -1;
        }
        return __rt_sigprocmask(how, set, oldset, _NSIG / 8);

Again, _NSIG / 8 must be correct here, or it will fail always.



Hope this helps

--
vda
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to