Package: strace
version: 4.5.18-1
Severity: grave
Architecture: hppa
Tags: Patch

Strace is *unusable* on hppa.

This bug supercedes bug #437928, updates the patches listed there, and
fixes the most recent issues.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=437928

Problems:
* Traced process function descriptors are accessed causing faults.
* More than maximum number of syscall arguments accessed causing upeek failures.
* Missing syscalls.
* Incorrect processing of some IPC syscalls.

Please apply the attached patch to fix all of these issues.

It is critical that strace be fixed, the debian-porters are attempting
to track down buildd instability issues and without a working strace
this makes it difficult.

Cheers,
Carlos.
From: Carlos O'Donell <car...@systemhalted.org>

Miscellaneous hppa fixes

Add missing syscalls, handle IPC syscalls correctly,
avoid manipulationg function pointers, and handle
syscall arguments correctly.

This patch is based on work by Kyle McMartin and 
Helge Deller.

	* ipc.c (sys_shmat): hppa does not have a kernel 
	multiplexer for IPC.
	* linux/hppa/syscallend.h: Add missing syscalls.
	* signal.c (sys_sigaction): Avoid manipulating
	function pointers.
	(sys_rt_sigaction): Likewise.

Signed-off-by: Carlos O'Donell <car...@systemhalted.org>
---

diff -urN strace-4.5.18_orig/ipc.c strace-4.5.18/ipc.c
--- strace-4.5.18_orig/ipc.c	2007-01-15 15:25:52.000000000 -0500
+++ strace-4.5.18/ipc.c	2009-09-13 21:58:31.000000000 -0400
@@ -387,7 +387,8 @@
 		}
 		if (syserror(tcp))
 			return 0;
-#ifdef LINUX
+/* HPPA does not use an IPC multiplexer.  */
+#ifdef LINUX && !defined(HPPA) 
 		if (umove(tcp, tcp->u_arg[2], &raddr) < 0)
 			return RVAL_NONE;
 		tcp->u_rval = raddr;
diff -urN strace-4.5.18_orig/linux/hppa/syscallent.h strace-4.5.18/linux/hppa/syscallent.h
--- strace-4.5.18_orig/linux/hppa/syscallent.h	2008-07-17 21:23:49.000000000 -0400
+++ strace-4.5.18/linux/hppa/syscallent.h	2009-09-13 22:06:20.000000000 -0400
@@ -197,10 +197,10 @@
 	{ 4,	TI,	sys_msgrcv,		"msgrcv"		}, /* 189 */
 	{ 4,	TI,	sys_msgget,		"msgget"		}, /* 190 */
 	{ 4,	TI,	sys_msgctl,		"msgctl"		}, /* 191 */
-	{ 4,	TI,	sys_shmat,		"shmat"			}, /* 192 */
-	{ 4,	TI,	sys_shmdt,		"shmdt"			}, /* 193 */
-	{ 4,	TI,	sys_shmget,		"shmget"		}, /* 194 */
-	{ 4,	TI,	sys_shmctl,		"shmctl"		}, /* 195 */
+	{ 3,	TI,	sys_shmat,		"shmat"			}, /* 192 */
+	{ 1,	TI,	sys_shmdt,		"shmdt"			}, /* 193 */
+	{ 3,	TI,	sys_shmget,		"shmget"		}, /* 194 */
+	{ 3,	TI,	sys_shmctl,		"shmctl"		}, /* 195 */
 	{ 5,	0,	sys_getpmsg,		"getpmsg"		}, /* 196 */
 	{ 5,	0,	sys_putpmsg,		"putpmsg"		}, /* 197 */
 	{ 2,	TF,	sys_lstat64,		"lstat64"		}, /* 198 */
@@ -302,4 +302,25 @@
 	{ 4,	TD,	printargs,		"vmsplice"		}, /* 294 */
 	{ 6,	0,	sys_move_pages,		"move_pages"		}, /* 295 */
 	{ 3,	0,	sys_getcpu,		"getcpu"		}, /* 296 */
-	{ 5,	TD,	sys_epoll_pwait,	"epoll_pwait"		}, /* 297 */
+	{ 6,	TD,	sys_epoll_pwait,	"epoll_pwait"		}, /* 297 */
+	{ 3,	TF,	sys_statfs64,		"statfs64"		}, /* 298 */
+	{ 3,	TD,	sys_fstatfs64,		"fstatfs64"		}, /* 299 */
+	{ 4,	0,	printargs,		"kexec_load"		}, /* 300 */
+	{ 4,	TD|TF,	sys_utimensat,		"utimensat"		}, /* 301 */
+	{ 3,	TD,	printargs,		"signalfd"		}, /* 302 */
+	{ 4,	TD,	printargs,		"timerfd"		}, /* 303 */
+	{ 1,	TD,	sys_eventfd,		"eventfd"		}, /* 304 */
+	{ 6,	TF,	sys_fallocate,		"fallocate"		}, /* 305 */
+	{ 2,	TD,	sys_timerfd_create,	"timerfd_create"	}, /* 306 */
+	{ 4,	TD,	sys_timerfd_settime,	"timerfd_settime"	}, /* 307 */
+	{ 2,	TD,	sys_timerfd_gettime,	"timerfd_gettime"	}, /* 308 */
+	{ 4,	TD|TS,	printargs,		"signalfd4"		}, /* 309 */
+	{ 2,	TD,	printargs,		"eventfd2"		}, /* 310 */
+	{ 1,	0,	printargs,		"epoll_create1"		}, /* 311 */
+	{ 3,	TD,	printargs,		"dup3"			}, /* 312 */
+	{ 2,	TD,	printargs,		"pipe2"			}, /* 313 */
+	{ 1,	TD,	printargs,		"inotify_init1"		}, /* 314 */
+	{ 5,	TD,	printargs,		"preadv"		}, /* 315 */
+	{ 5,	TD,	printargs,		"pwritev"		}, /* 316 */
+	{ 4,	TP|TS,	printargs,		"rt_tgsigqueueinfo"	}, /* 317 */
+	{ 5,	0,	printargs,		"perf_counter_open"	}, /* 318 */
diff -urN strace-4.5.18_orig/signal.c strace-4.5.18/signal.c
--- strace-4.5.18_orig/signal.c	2008-08-19 21:59:40.000000000 -0400
+++ strace-4.5.18/signal.c	2009-09-13 22:00:50.000000000 -0400
@@ -1120,11 +1120,19 @@
 	else if (umove(tcp, addr, &sa) < 0)
 		tprintf("{...}");
 	else {
-		if (sa.SA_HANDLER == SIG_ERR)
+ 		/* Architectures using function pointers, like
+ 		 * hppa, may need to manipulate the function pointer
+ 		 * to compute the result of a comparison. However,
+ 		 * the SA_HANDLER function pointer exists only in 
+ 		 * the address space of the traced process, and can't
+ 		 * be manipulated by strace. In order to prevent the 
+ 		 * compiler from generating code to manipulate 
+ 		 * SA_HANDLER we cast the function pointers to long. */
+		if ((long)sa.SA_HANDLER == (long)SIG_ERR)
 			tprintf("{SIG_ERR, ");
-		else if (sa.SA_HANDLER == SIG_DFL)
+		else if ((long)sa.SA_HANDLER == (long)SIG_DFL)
 			tprintf("{SIG_DFL, ");
-		else if (sa.SA_HANDLER == SIG_DFL) {
+		else if ((long)sa.SA_HANDLER == (long)SIG_DFL) {
 #ifndef USE_PROCFS
 			if (tcp->u_arg[0] == SIGTRAP) {
 				tcp->flags |= TCB_SIGTRAPPED;
@@ -1883,11 +1891,19 @@
 	else if (umove(tcp, addr, &sa) < 0)
 		tprintf("{...}");
 	else {
-		if (sa.__sigaction_handler.__sa_handler == SIG_ERR)
+ 		/* Architectures using function pointers, like
+ 		 * hppa, may need to manipulate the function pointer
+ 		 * to compute the result of a comparison. However,
+ 		 * the SA_HANDLER function pointer exists only in 
+ 		 * the address space of the traced process, and can't
+ 		 * be manipulated by strace. In order to prevent the 
+		 * compiler from generating code to manipulate 
+	 	 * SA_HANDLER we cast the function pointers to long. */
+		if ((long)sa.__sigaction_handler.__sa_handler == (long)SIG_ERR)
 			tprintf("{SIG_ERR, ");
-		else if (sa.__sigaction_handler.__sa_handler == SIG_DFL)
+		else if ((long)sa.__sigaction_handler.__sa_handler == (long)SIG_DFL)
 			tprintf("{SIG_DFL, ");
-		else if (sa.__sigaction_handler.__sa_handler == SIG_DFL)
+		else if ((long)sa.__sigaction_handler.__sa_handler == (long)SIG_DFL)
 			tprintf("{SIG_IGN, ");
 		else
 			tprintf("{%#lx, ",
diff -urN strace-4.5.18_orig/syscall.c strace-4.5.18/syscall.c
--- strace-4.5.18_orig/syscall.c	2008-08-24 23:16:26.000000000 -0400
+++ strace-4.5.18/syscall.c	2009-09-13 22:02:24.000000000 -0400
@@ -2095,13 +2095,19 @@
 #elif defined (HPPA)
 	{
 		int i;
-
+ 		long args[] = { PT_GR26-4*0, PT_GR26-4*1,
+ 				PT_GR26-4*2, PT_GR26-4*3,
+ 				PT_GR26-4*4, PT_GR26-4*5 };
+ 		
+ 		/* How many arguments does this syscall have?  */
 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+ 			/* Syscall is known, and number of arguments is known.  */
 			tcp->u_nargs = sysent[tcp->scno].nargs;
 		else
-     	        	tcp->u_nargs = MAX_ARGS;
+ 			/* Unknown syscall, assume maximum number of arguments.  */
+ 			tcp->u_nargs = sizeof(args)/sizeof(args[0]);
 		for (i = 0; i < tcp->u_nargs; i++) {
-			if (upeek(pid, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
+			if (upeek(pid, args[i], &tcp->u_arg[i]) < 0)
 				return -1;
 		}
 	}

Reply via email to