Set TCB_STARTUP only _after_ we attached.
This fixes logic in detach() which thinks that TCB_STARTUP
means that we are already attached, but did not see SIGSTOP yet.
This also allows to get rid of TCB_ATTACH_DONE flag.
* process.c (internal_fork): Set TCB_STARTUP after attach.
* strace.c (startup_attach): Likewise.
(startup_child): Likewise.
(alloc_tcb): Do not set TCB_STARTUP on tcb allocation - we are
not attached yet.
(trace): Set TCB_STARTUP when we detech an auto-attached child.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
diff --git a/process.c b/process.c
index c235a3d..45d71c4 100644
--- a/process.c
+++ b/process.c
@@ -487,6 +487,7 @@
tcpchild = alloctcb(tcp->u_rval);
if (proc_open(tcpchild, 2) < 0)
droptcb(tcpchild);
+ tcpchild->flags |= TCB_STARTUP;
}
return 0;
}
@@ -858,7 +859,7 @@
}
#endif /* !oldway */
#endif /* SUNOS4 */
- tcpchild->flags |= TCB_ATTACHED;
+ tcpchild->flags |= TCB_ATTACHED | TCB_STARTUP;
/* Child has BPT too, must be removed on first occasion */
if (bpt) {
tcpchild->flags |= TCB_BPTSET;
diff --git a/strace.c b/strace.c
index 5ed3da6..e95ff5c 100644
--- a/strace.c
+++ b/strace.c
@@ -471,8 +471,11 @@
if (dir != NULL) {
unsigned int ntid = 0, nerr = 0;
struct dirent *de;
- int tid;
+
while ((de = readdir(dir)) != NULL) {
+ struct tcb *cur_tcp;
+ int tid;
+
if (de->d_fileno == 0)
continue;
tid = atoi(de->d_name);
@@ -483,23 +486,22 @@
++nerr;
if (debug)
fprintf(stderr, "attach to pid %d failed\n", tid);
+ continue;
}
- else {
- if (debug)
- fprintf(stderr, "attach to pid %d succeeded\n", tid);
- if (tid != tcp->pid) {
- struct tcb *new_tcp = alloctcb(tid);
- new_tcp->flags |= TCB_ATTACHED|TCB_ATTACH_DONE;
- }
- }
- if (interactive) {
- sigprocmask(SIG_SETMASK, &empty_set, NULL);
- if (interrupted)
- goto ret;
- sigprocmask(SIG_BLOCK, &blocked_set, NULL);
- }
+ if (debug)
+ fprintf(stderr, "attach to pid %d succeeded\n", tid);
+ cur_tcp = tcp;
+ if (tid != tcp->pid)
+ cur_tcp = alloctcb(tid);
+ cur_tcp->flags |= TCB_ATTACHED|TCB_ATTACH_DONE|TCB_STARTUP;
}
closedir(dir);
+ if (interactive) {
+ sigprocmask(SIG_SETMASK, &empty_set, NULL);
+ if (interrupted)
+ goto ret;
+ sigprocmask(SIG_BLOCK, &blocked_set, NULL);
+ }
ntid -= nerr;
if (ntid == 0) {
perror("attach: ptrace(PTRACE_ATTACH, ...)");
@@ -521,6 +523,7 @@
droptcb(tcp);
continue;
}
+ tcp->flags |= TCB_STARTUP;
if (debug)
fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
@@ -714,6 +717,7 @@
if (!daemonized_tracer) {
tcp = alloctcb(pid);
+ tcp->flags |= TCB_STARTUP;
}
else {
/* With -D, *we* are child here, IOW: different pid. Fetch it: */
@@ -1270,7 +1274,7 @@
if ((tcp->flags & TCB_INUSE) == 0) {
memset(tcp, 0, sizeof(*tcp));
tcp->pid = pid;
- tcp->flags = TCB_INUSE | TCB_STARTUP;
+ tcp->flags = TCB_INUSE;
tcp->outf = outf; /* Initialise to current out file */
#ifdef USE_PROCFS
tcp->pfd = -1;
@@ -2417,7 +2421,7 @@
child so that we know how to do clearbpt
in the child. */
tcp = alloctcb(pid);
- tcp->flags |= TCB_ATTACHED;
+ tcp->flags |= TCB_ATTACHED | TCB_STARTUP;
if (!qflag)
fprintf(stderr, "Process %d attached\n",
pid);