[PATCH] small fixes to ^C handling

Denys Vlasenko dvlasenk at redhat.com
Thu Apr 23 13:45:15 UTC 2009


Interrupting strace with ^C works in practice,
but from code inspection I see some scenarios
when we may leave some tracees stopped when
strace exits.

This patch catches these cases by not allowing
^C exit to commence until all collected tracees
are dealt with.

Changelog:

* strace.c (collect_stopped_tcbs): Expose remembered_pid
static variable.
(trace): Do not exit yet if ^C pressed but
remembered_pid is nonzero. It needs to be handled first.
(handle_stopped_tcbs): Remove ^C test, we must not exit
until we processed _all_ collected tasks.
--
vda


--- strace.c	20 Apr 2009 18:20:18 -0000	1.115
+++ strace.c	23 Apr 2009 13:36:58 -0000
@@ -2249,13 +2249,14 @@
 }
 #endif
 
+#ifdef LINUX
+static int remembered_pid;
+static int remembered_status;
+#endif
+
 static struct tcb *
 collect_stopped_tcbs(void)
 {
-#ifdef LINUX
-	static int remembered_pid;
-	static int remembered_status;
-#endif
 	int pid;
 	int wait_errno;
 	int status;
@@ -2718,9 +2719,6 @@
 			tcp->flags &= ~TCB_SUSPENDED;
 			continue;
 		}
-		/* we handled the STATUS, we are permitted to interrupt now. */
-		if (interrupted)
-			return 0;
 		if (trace_syscall(tcp) < 0) {
 			/* trace_syscall printed incompletely decoded syscall,
 			 * add error indicator.
@@ -2793,8 +2791,13 @@
 		 * To fix it, we collect *all* waitable tasks, then handle
 		 * them all, then repeat.
 		 */
-		if (interrupted)
+		/* If remembered_pid exists, there is one extra tracee
+		 * "collected" earlier. Do not exit in this case, we need
+		 * to handle it first.
+		 */
+		if (remembered_pid == 0 && interrupted) {
 			return 0;
+		}
 		tcbs = collect_stopped_tcbs();
 		if (!tcbs)
 			break;






More information about the Strace-devel mailing list