[PATCH] fix sigaction display on 32/64bit systems
Denys Vlasenko
dvlasenk at redhat.com
Mon Mar 30 15:47:55 UTC 2009
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;
}
More information about the Strace-devel
mailing list