Before this patch:

ioctl(255, TIOCGPGRP, [3832])           = 0
rt_sigaction(SIGTSTP, {0x1400000000000001, [QUIT TRAP RT_3 RT_6 RT_8 RT_9 RT_10 
RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], 
SA_RESTORER|SA_STACK|SA_RESTART|SA_INTERRUPT|SA_NODEFER|SA_RESETHAND|SA_SIGINFO|0x3c1c030,
 0x100000000}, 8) = 0
rt_sigaction(SIGTTIN, {0x1400000000000001, [HUP QUIT TRAP RT_3 RT_6 RT_8 RT_9 
RT_10 RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x100000000}, 8) = 0
rt_sigaction(SIGTTOU, {0x1400000000000001, [INT QUIT TRAP RT_3 RT_6 RT_8 RT_9 
RT_10 RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x100000000}, 8) = 0
rt_sigaction(SIGINT, {0x1400000000000001, [INT RT_3 RT_6 RT_8 RT_9 RT_10 RT_11 
RT_15 RT_18 RT_19 RT_20 RT_28], SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, 
{SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 
0x100000000}, 8) = 0
rt_sigaction(SIGQUIT, {0x1400000000000001, [HUP INT RT_3 RT_6 RT_8 RT_9 RT_10 
RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x100000000}, 8) = 0
rt_sigaction(SIGTERM, {0x1400000000000001, [HUP INT QUIT ILL RT_3 RT_6 RT_8 
RT_9 RT_10 RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x100000000}, 8) = 0
rt_sigaction(SIGHUP, {0x14000000080899e8, [HUP RT_3 RT_6 RT_8 RT_9 RT_10 RT_11 
RT_15 RT_18 RT_19 RT_20 RT_28], SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, 
{SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 
0x80899e800000000}, 8) = 0
rt_sigaction(SIGILL, {0x14000000080899e8, [QUIT RT_3 RT_6 RT_8 RT_9 RT_10 RT_11 
RT_15 RT_18 RT_19 RT_20 RT_28], SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, 
{SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 
0x80899e800000000}, 8) = 0
rt_sigaction(SIGTRAP, {0x14000000080899e8, [HUP QUIT RT_3 RT_6 RT_8 RT_9 RT_10 
RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x80899e800000000}, 8) = 0
rt_sigaction(SIGABRT, {0x14000000080899e8, [INT QUIT RT_3 RT_6 RT_8 RT_9 RT_10 
RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x80899e800000000}, 8) = 0
rt_sigaction(SIGBUS, {0x14000000080899e8, [HUP INT QUIT RT_3 RT_6 RT_8 RT_9 
RT_10 RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x80899e800000000}, 8) = 0
rt_sigaction(SIGFPE, {0x14000000080899e8, [ILL RT_3 RT_6 RT_8 RT_9 RT_10 RT_11 
RT_15 RT_18 RT_19 RT_20 RT_28], SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, 
{SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 
0x80899e800000000}, 8) = 0
rt_sigaction(SIGSEGV, {0x14000000080899e8, [HUP INT ILL RT_3 RT_6 RT_8 RT_9 
RT_10 RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x80899e800000000}, 8) = 0
rt_sigaction(SIGPIPE, {0x14000000080899e8, [HUP QUIT ILL RT_3 RT_6 RT_8 RT_9 
RT_10 RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|SA_NODEFER|SA_NOCLDWAIT|0x36e6970, 
0x80899e800000000}, 8) = 0
rt_sigaction(SIGALRM, {0x14000000080899e8, [INT QUIT ILL RT_3 RT_6 RT_8 RT_9 
RT_10 RT_11 RT_15 RT_18 RT_19 RT_20 RT_28], 
SA_STACK|SA_NOCLDSTOP|SA_NOCLDWAIT|0x487f8}, {SIG_DFL, [IO RT_1 RT_3 RT_5 RT_11 
RT_25], SA_RESTORER|SA_INTERRUPT|0x8322a0, 0x80899e800000000}, 8) = 0
setpgid(0, 0)                           = 0

struct sigaction is totally misinterpreted.

After patch:

ioctl(255, TIOCGPGRP, [3832])           = 0
rt_sigaction(SIGTSTP, {SIG_IGN, [TSTP], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_IGN, [TTIN], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {SIG_IGN, [TTOU], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_IGN, [TERM], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGHUP, {0x80899e8, [HUP], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGILL, {0x80899e8, [ILL], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTRAP, {0x80899e8, [TRAP], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGABRT, {0x80899e8, [ABRT], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGBUS, {0x80899e8, [BUS], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGFPE, {0x80899e8, [FPE], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGSEGV, {0x80899e8, [SEGV], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGPIPE, {0x80899e8, [PIPE], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGALRM, {0x80899e8, [ALRM], SA_RESTORER|SA_RESTART, 0x80487fb}, 
{SIG_DFL, [], 0}, 8) = 0
setpgid(0, 0)                           = 0

Changelog:

        * signal.c: Include <stdint.h>
        (struct new_sigaction): Simplify
        (sys_rt_sigprocmask): If personality is not native
        and is 32-bit, translate 32-bit struct sigaction
        to native one.

--
vda



diff -d -urpN strace.3/signal.c strace.4/signal.c
--- strace.3/signal.c   2009-02-27 21:32:53.000000000 +0100
+++ strace.4/signal.c   2009-03-30 16:50:20.000000000 +0200
@@ -35,6 +35,7 @@
 
 #include "defs.h"
 
+#include <stdint.h>
 #include <signal.h>
 #include <sys/user.h>
 #include <fcntl.h>
@@ -1860,25 +1861,29 @@ sys_rt_sigprocmask(tcp)
 /* Structure describing the action to be taken when a signal arrives.  */
 struct new_sigaction
 {
-       union
-       {
-               __sighandler_t __sa_handler;
-               void (*__sa_sigaction) (int, siginfo_t *, void *);
-       }
-       __sigaction_handler;
+       __sighandler_t __sa_handler;
        unsigned long sa_flags;
        void (*sa_restorer) (void);
-       unsigned long int sa_mask[2];
+       /* Kernel treats sa_mask as an array of longs. */
+       unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
+};
+/* Same for i386-on-x86_64 and similar cases */
+struct new_sigaction32
+{
+       uint32_t __sa_handler;
+       uint32_t sa_flags;
+       uint32_t sa_restorer;
+       uint32_t sa_mask[2 * (NSIG / sizeof(long) ? NSIG / sizeof(long) : 1)];
 };
 
 
 int
-sys_rt_sigaction(tcp)
-       struct tcb *tcp;
+sys_rt_sigaction(struct tcb *tcp)
 {
        struct new_sigaction sa;
        sigset_t sigset;
        long addr;
+       int r;
 
        if (entering(tcp)) {
                printsignal(tcp->u_arg[0]);
@@ -1886,22 +1891,56 @@ sys_rt_sigaction(tcp)
                addr = tcp->u_arg[1];
        } else
                addr = tcp->u_arg[2];
-       if (addr == 0)
+
+       if (addr == 0) {
                tprintf("NULL");
-       else if (!verbose(tcp))
+               goto after_sa;
+       }
+       if (!verbose(tcp)) {
                tprintf("%#lx", addr);
-       else if (umove(tcp, addr, &sa) < 0)
+               goto after_sa;
+       }
+       if (personality_wordsize[current_personality] != sizeof(sa.sa_flags)
+        && personality_wordsize[current_personality] == 4
+       ) {
+               struct new_sigaction32 sa32;
+               r = umove(tcp, addr, &sa32);
+               if (r >= 0) {
+                       memset(&sa, 0, sizeof(sa));
+                       sa.__sa_handler = (void*)(unsigned 
long)sa32.__sa_handler;
+                       sa.sa_flags     = sa32.sa_flags;
+                       sa.sa_restorer  = (void*)(unsigned 
long)sa32.sa_restorer;
+                       /* Kernel treats sa_mask as an array of longs.
+                        * For 32-bit process, "long" is uint32_t, thus, for 
example,
+                        * 32th bit in sa_mask will end up as bit 0 in 
sa_mask[1].
+                        * But for (64-bit) kernel, 32th bit in sa_mask is
+                        * 32th bit in 0th (64-bit) long!
+                        * For little-endian, it's the same.
+                        * For big-endian, we swap 32-bit words.
+                        */
+                       sa.sa_mask[0] = sa32.sa_mask[0] + 
((long)(sa32.sa_mask[1]) << 32);
+               }
+       } else {
+               r = umove(tcp, addr, &sa);
+       }
+       if (r < 0) {
                tprintf("{...}");
-       else {
-               if (sa.__sigaction_handler.__sa_handler == SIG_ERR)
+               goto after_sa;
+       }
+       {
+               if (sa.__sa_handler == SIG_ERR)
                        tprintf("{SIG_ERR, ");
-               else if (sa.__sigaction_handler.__sa_handler == SIG_DFL)
+               else if (sa.__sa_handler == SIG_DFL)
                        tprintf("{SIG_DFL, ");
-               else if (sa.__sigaction_handler.__sa_handler == SIG_IGN)
+               else if (sa.__sa_handler == SIG_IGN)
                        tprintf("{SIG_IGN, ");
                else
-                       tprintf("{%#lx, ",
-                               (long) sa.__sigaction_handler.__sa_handler);
+                       tprintf("{%#lx, ", (long) sa.__sa_handler);
+               /* Questionable code below.
+                * Kernel won't handle sys_rt_sigaction
+                * with wrong sigset size (just returns EINVAL)
+                * therefore tcp->u_arg[3(4)] _must_ be NSIG / 8 here,
+                * and we always use smaller memcpy. */
                sigemptyset(&sigset);
 #ifdef LINUXSPARC
                if (tcp->u_arg[4] <= sizeof(sigset))
@@ -1921,6 +1960,8 @@ sys_rt_sigaction(tcp)
 #endif
                tprintf("}");
        }
+
+ after_sa:
        if (entering(tcp))
                tprintf(", ");
        else
@@ -1929,7 +1970,7 @@ sys_rt_sigaction(tcp)
 #elif defined(ALPHA)
                tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
 #else
-               tprintf(", %lu", addr = tcp->u_arg[3]);
+               tprintf(", %lu", tcp->u_arg[3]);
 #endif
        return 0;
 }



------------------------------------------------------------------------------
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to