* process.c: Add a comment. No code changes.
* strace.c (collect_stopped_tcbs): Stop reversing list of stopped
tcp's. I'm not totally convinced it is crucial, but this is surely
fits the concept of "least surprise".
Do not collect TCB_SUSPENDED tcp's (this is closer to how
it was before).
(handle_stopped_tcbs): Remove the code to reject TCB_SUSPENDED tcp's,
it's done earlier now. In an unobvious way, this was causing
SIGSTOPs from freshly attached children to be misinterpreted.
diff --git a/ChangeLog b/ChangeLog
index 5bfd7db..0102ce8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-01-17 Denys Vlasenko <dvlasenk@redhat.com>
+
+ * process.c: Add a comment. No code changes.
+ * strace.c (collect_stopped_tcbs): Stop reversing list of stopped
+ tcp's. I'm not totally convinced it is crucial, but this is surely
+ fits the concept of "least surprise".
+ Do not collect TCB_SUSPENDED tcp's (this is closer to how
+ it was before).
+ (handle_stopped_tcbs): Remove the code to reject TCB_SUSPENDED tcp's,
+ it's done earlier now. In an unobvious way, this was causing
+ SIGSTOPs from freshly attached children to be misinterpreted.
+
2009-01-14 Denys Vlasenko <dvlasenk@redhat.com>
* linux/bfin/syscallent.h: sys_futex has 6 parameters, not 5.
diff --git a/process.c b/process.c
index 03cd251..7107361 100644
--- a/process.c
+++ b/process.c
@@ -963,6 +963,9 @@
clearbpt(tcpchild);
tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
+ /* TCB_SUSPENDED tasks are not collected by waitpid
+ * loop, and left stopped. Restart it:
+ */
if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
return -1;
diff --git a/strace.c b/strace.c
index 57945db..80d468a 100644
--- a/strace.c
+++ b/strace.c
@@ -2279,7 +2279,8 @@
struct rusage ru;
struct rusage* ru_ptr = cflag ? &ru : NULL;
int wnohang = 0;
- struct tcb *found_tcps = NULL;
+ struct tcb *found_tcps;
+ struct tcb **nextp = &found_tcps;
#ifdef __WALL
int wait4_options = __WALL;
#endif
@@ -2401,30 +2402,6 @@
tcp->stime = ru.ru_stime;
#endif
}
- tcp->wait_status = status;
-#ifdef LINUX
- tcp->next_need_service = found_tcps;
- found_tcps = tcp;
- wnohang = WNOHANG;
-#endif
-#ifdef SUNOS4
- /* Probably need to replace wait with waitpid
- * and loop on Sun too, but I can't test it. Volunteers?
- */
- break;
-#endif
- } /* while (1) - collecting all stopped/exited tracees */
-
- return tcp;
-}
-
-static int
-handle_stopped_tcbs(struct tcb *tcp)
-{
- for (; tcp; tcp = tcp->next_need_service) {
- int pid;
- int status;
-
if (tcp->flags & TCB_SUSPENDED) {
/*
* Apparently, doing any ptrace() call on a stopped
@@ -2437,6 +2414,37 @@
continue;
}
+ tcp->wait_status = status;
+#ifdef LINUX
+ /* It is important to not invert the order of tasks
+ * to process. For one, alloc_tcb() above picks newly forked
+ * threads in some order, processing of them and their parent
+ * should be in the same order, otherwise bad things happen
+ * (misinterpreted SIGSTOPs and such).
+ */
+ *nextp = tcp;
+ nextp = &tcp->next_need_service;
+ wnohang = WNOHANG;
+#endif
+#ifdef SUNOS4
+ /* Probably need to replace wait with waitpid
+ * and loop on Sun too, but I can't test it. Volunteers?
+ */
+ break;
+#endif
+ }
+
+ *nextp = NULL;
+ return found_tcps;
+}
+
+static int
+handle_stopped_tcbs(struct tcb *tcp)
+{
+ for (; tcp; tcp = tcp->next_need_service) {
+ int pid;
+ int status;
+
outf = tcp->outf;
status = tcp->wait_status;
pid = tcp->pid;