[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