From: Denys Vlasenko Date: Mon, 5 Sep 2011 11:59:39 +0000 (+0200) Subject: Set TCB_STARTUP only _after_ we attached. X-Git-Tag: v4.7~258 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=381dbc22929428579f50d9b0b39193feba93dcfd;p=strace 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 --- diff --git a/process.c b/process.c index c235a3d9..45d71c42 100644 --- a/process.c +++ b/process.c @@ -487,6 +487,7 @@ internal_fork(struct tcb *tcp) tcpchild = alloctcb(tcp->u_rval); if (proc_open(tcpchild, 2) < 0) droptcb(tcpchild); + tcpchild->flags |= TCB_STARTUP; } return 0; } @@ -858,7 +859,7 @@ internal_fork(struct tcb *tcp) } #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 5ed3da67..e95ff5ce 100644 --- a/strace.c +++ b/strace.c @@ -471,8 +471,11 @@ startup_attach(void) 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 @@ startup_attach(void) ++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 @@ startup_attach(void) droptcb(tcp); continue; } + tcp->flags |= TCB_STARTUP; if (debug) fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); @@ -714,6 +717,7 @@ startup_child(char **argv) 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 @@ alloc_tcb(int pid, int command_options_parsed) 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 @@ trace() 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);