[PATCH 5/5] Unify post-execve SIGTRAP check across all arches

Denys Vlasenko dvlasenk at redhat.com
Mon Aug 22 10:30:26 UTC 2011


On Mon, 2011-08-22 at 12:21 +0200, Denys Vlasenko wrote:
> 5. Move post-execve SIGTRAP from get_scno_on_sysenter (multitude of
> places on many architectures) to a single location in
> trace_syscall_entering. This loosens the logic for some arches, since
> many of them had additional checks such as scno == 0. So maybe this last
> patch is not 100% safe. (However, on non-ancient Linux kernels we should
> never have post-execve SIGTRAP in the first place, by virtue of using
> PTRACE_O_TRACEEXEC.)

diff -d -urpN strace.4/syscall.c strace.5/syscall.c
--- strace.4/syscall.c	2011-08-22 04:01:28.851814943 +0200
+++ strace.5/syscall.c	2011-08-22 04:11:21.004866031 +0200
@@ -756,12 +756,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 
 #ifdef LINUX
 # if defined(S390) || defined(S390X)
-	if (tcp->flags & TCB_WAITEXECVE) {
-		/* This is the post-execve SIGTRAP. */
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
-
 	if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
 		return -1;
 
@@ -845,11 +839,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 # elif defined (POWERPC)
 	if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
 		return -1;
-	/* Check if this is the post-execve SIGTRAP. */
-	if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
 #  ifdef POWERPC64
 	/* TODO: speed up strace by not doing this at every syscall.
 	 * We only need to do it after execve.
@@ -874,19 +863,10 @@ get_scno_on_sysenter(struct tcb *tcp)
 	}
 #  endif
 # elif defined(AVR32)
-	/*
-	 * Read complete register set in one go.
-	 */
+	/* Read complete register set in one go. */
 	if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, &regs) < 0)
 		return -1;
-
 	scno = regs.r8;
-
-	/* Check if this is the post-execve SIGTRAP. */
-	if (tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
 # elif defined(BFIN)
 	if (upeek(tcp, PT_ORIG_P0, &scno))
 		return -1;
@@ -971,15 +951,8 @@ get_scno_on_sysenter(struct tcb *tcp)
 		if (upeek(tcp, PT_R15, &scno) < 0)
 			return -1;
 	}
-	/* Check if this is the post-execve SIGTRAP. */
-	if (tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
 # elif defined (ARM)
-	/*
-	 * Read complete register set in one go.
-	 */
+	/* Read complete register set in one go. */
 	if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
 		return -1;
 
@@ -987,12 +960,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 	 * We only need to grab the syscall number on syscall entry.
 	 */
 	if (regs.ARM_ip == 0) {
-		/* Check if this is the post-execve SIGTRAP. */
-		if (tcp->flags & TCB_WAITEXECVE) {
-			tcp->flags &= ~TCB_WAITEXECVE;
-			return 0;
-		}
-
 		/*
 		 * Note: we only deal with only 32-bit CPUs here.
 		 */
@@ -1010,14 +977,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 			if (errno)
 				return -1;
 
-		/* FIXME: bogus check? it is already done before,
-		 * so we never can see it here?
-		 */
-			if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
-				tcp->flags &= ~TCB_WAITEXECVE;
-				return 0;
-			}
-
 			/* Handle the EABI syscall convention.  We do not
 			   bother converting structures between the two
 			   ABIs, but basic functionality should work even
@@ -1063,13 +1022,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 	r2 = regs[REG_V0];
 
 	scno = r2;
-
-	/* Check if this is the post-execve SIGTRAP. */
-	if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
-
 	if (scno < 0 || scno > nsyscalls) {
 		if (a3 == 0 || a3 == -1) {
 			if (debug)
@@ -1083,12 +1035,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 	if (upeek(tcp, REG_V0, &scno) < 0)
 		return -1;
 
-	/* Check if this is the post-execve SIGTRAP. */
-	if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
-
 	if (scno < 0 || scno > nsyscalls) {
 		if (a3 == 0 || a3 == -1) {
 			if (debug)
@@ -1099,16 +1045,9 @@ get_scno_on_sysenter(struct tcb *tcp)
 # elif defined (ALPHA)
 	if (upeek(tcp, REG_A3, &a3) < 0)
 		return -1;
-
 	if (upeek(tcp, REG_R0, &scno) < 0)
 		return -1;
 
-	/* Check if this is the post-execve SIGTRAP. */
-	if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
-
 	/*
 	 * Do some sanity checks to figure out if it's
 	 * really a syscall entry
@@ -1164,11 +1103,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 		set_personality(1);
 		break;
 	default:
-		/* Check if this is the post-execve SIGTRAP. */
-		if (tcp->flags & TCB_WAITEXECVE) {
-			tcp->flags &= ~TCB_WAITEXECVE;
-			return 0;
-		}
 #  if defined (SPARC64)
 		fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
 #  else
@@ -1189,11 +1123,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 # elif defined(HPPA)
 	if (upeek(tcp, PT_GR20, &scno) < 0)
 		return -1;
-	/* Check if this is the post-execve SIGTRAP. */
-	if (tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
 # elif defined(SH)
 	/*
 	 * In the new syscall ABI, the system call number is in R3.
@@ -1214,34 +1143,16 @@ get_scno_on_sysenter(struct tcb *tcp)
 				correct_scno);
 		scno = correct_scno;
 	}
-
-	/* Check if this is the post-execve SIGTRAP. */
-	if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
 # elif defined(SH64)
 	if (upeek(tcp, REG_SYSCALL, &scno) < 0)
 		return -1;
 	scno &= 0xFFFF;
-
-	/* Check if this is the post-execve SIGTRAP. */
-	if (tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
 # elif defined(CRISV10) || defined(CRISV32)
 	if (upeek(tcp, 4*PT_R9, &scno) < 0)
 		return -1;
 # elif defined(TILE)
 	if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
 		return -1;
-
-	/* Check if this is the post-execve SIGTRAP. */
-	if (tcp->flags & TCB_WAITEXECVE) {
-		tcp->flags &= ~TCB_WAITEXECVE;
-		return 0;
-	}
 # elif defined(MICROBLAZE)
 	if (upeek(tcp, 0, &scno) < 0)
 		return -1;
@@ -1302,9 +1213,7 @@ get_scno_on_sysexit(struct tcb *tcp)
 # if defined(S390) || defined(S390X)
 # elif defined (POWERPC)
 # elif defined(AVR32)
-	/*
-	 * Read complete register set in one go.
-	 */
+	/* Read complete register set in one go. */
 	if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, &regs) < 0)
 		return -1;
 # elif defined(BFIN)
@@ -1323,9 +1232,7 @@ get_scno_on_sysexit(struct tcb *tcp)
 	if (upeek(tcp, PT_R10, &r10) < 0)
 		return -1;
 # elif defined (ARM)
-	/*
-	 * Read complete register set in one go.
-	 */
+	/* Read complete register set in one go. */
 	if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
 		return -1;
 # elif defined (M68K)
@@ -1513,6 +1420,7 @@ syscall_fixup(struct tcb *tcp)
 		  == (TCB_INSYSCALL|TCB_WAITEXECVE))
 		 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
 		/*
+		 * Return from execve.
 		 * Fake a return value of zero.  We leave the TCB_WAITEXECVE
 		 * flag set for the post-execve SIGTRAP to see and reset.
 		 */
@@ -2422,6 +2330,14 @@ trace_syscall_entering(struct tcb *tcp)
 {
 	int res, scno_good;
 
+#if defined TCB_WAITEXECVE
+	if (tcp->flags & TCB_WAITEXECVE) {
+		/* This is the post-execve SIGTRAP. */
+		tcp->flags &= ~TCB_WAITEXECVE;
+		return 0;
+	}
+#endif
+
 	scno_good = res = get_scno_on_sysenter(tcp);
 	if (res == 0)
 		return res;
@@ -2591,9 +2507,6 @@ trace_syscall_exiting(struct tcb *tcp)
 	if (dtime || cflag)
 		gettimeofday(&tv, NULL);
 
-	/* BTW, why we don't just memorize syscall no. on entry
-	 * in tcp->something?
-	 */
 	scno_good = res = get_scno_on_sysexit(tcp);
 	if (res == 0)
 		return res;






More information about the Strace-devel mailing list