From: Dmitry V. Levin Date: Wed, 11 Oct 2006 22:55:25 +0000 (+0000) Subject: 2006-03-29 Dmitry V. Levin X-Git-Tag: v4.5.18~271 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76860f60d73bbdcc98725b6f8d7997ad0746cac2;p=strace 2006-03-29 Dmitry V. Levin Fix race conditions in tcb allocation. * process.c (fork_tcb): Return error code as documented. Do not print "tcb table full" error message. [USE_PROCFS] (internal_fork): Do not print "tcb table full" error message. [SYS_clone || SYS_clone2] (internal_clone, internal_fork): Call fork_tcb() before alloctcb(). Do not print "tcb table full" error message. * strace.c (main): Do not print "tcb table full" error message. (expand_tcbtab): Print error message in case of memory allocation failure. (alloctcb): Print error message when tcb table is full. (trace): Expand tcb table if necessary prior to allocating entry there. Do not print "tcb table full" error message. Fixes RH#180293. --- diff --git a/ChangeLog b/ChangeLog index bd4bde2c..a241c021 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-03-29 Dmitry V. Levin + + Fix race conditions in tcb allocation. + * process.c (fork_tcb): Return error code as documented. Do not + print "tcb table full" error message. + [USE_PROCFS] (internal_fork): Do not print "tcb table full" + error message. + [SYS_clone || SYS_clone2] (internal_clone, internal_fork): Call + fork_tcb() before alloctcb(). Do not print "tcb table full" + error message. + * strace.c (main): Do not print "tcb table full" error message. + (expand_tcbtab): Print error message in case of memory allocation + failure. + (alloctcb): Print error message when tcb table is full. + (trace): Expand tcb table if necessary prior to allocating + entry there. Do not print "tcb table full" error message. + Fixes RH#180293. + 2006-08-22 Roland McGrath * ipc.c (sys_msgget, sys_semget, sys_shmget): Show key values in hex. diff --git a/process.c b/process.c index 1e03ff5c..a0db041a 100644 --- a/process.c +++ b/process.c @@ -412,7 +412,7 @@ fork_tcb(struct tcb *tcp) if (nprocs == tcbtabsize) { if (expand_tcbtab()) { tcp->flags &= ~TCB_FOLLOWFORK; - fprintf(stderr, "sys_fork: tcb table full\n"); + return 1; } } @@ -474,10 +474,8 @@ struct tcb *tcp; return 0; if (syserror(tcp)) return 0; - if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) { - fprintf(stderr, "sys_fork: tcb table full\n"); + if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) return 0; - } if (proc_open(tcpchild, 2) < 0) droptcb(tcpchild); } @@ -833,10 +831,9 @@ struct tcb *tcp; } else #endif - if ((tcpchild = alloctcb(pid)) == NULL) { + if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) { if (bpt) clearbpt(tcp); - fprintf(stderr, " [tcb table full]\n"); kill(pid, SIGKILL); /* XXX */ return 0; } @@ -970,8 +967,7 @@ struct tcb *tcp; return 0; pid = tcp->u_rval; - if ((tcpchild = alloctcb(pid)) == NULL) { - fprintf(stderr, " [tcb table full]\n"); + if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) { kill(pid, SIGKILL); /* XXX */ return 0; } diff --git a/strace.c b/strace.c index 1553fb59..0da34abe 100644 --- a/strace.c +++ b/strace.c @@ -442,11 +442,8 @@ char *argv[]; tcp = NULL; else tcp = alloctcb(tid); - if (tcp == NULL) { - fprintf(stderr, "%s: out of memory\n", - progname); + if (tcp == NULL) exit(1); - } tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD|TCB_CLONE_DETACHED|TCB_FOLLOWFORK; tcbtab[c]->nchildren++; tcbtab[c]->nclone_threads++; @@ -626,7 +623,6 @@ Process %u attached - interrupt to quit\n", } default: if ((tcp = alloctcb(pid)) == NULL) { - fprintf(stderr, "tcb table full\n"); cleanup(); exit(1); } @@ -725,6 +721,8 @@ expand_tcbtab() if (newtab == NULL || newtcbs == NULL) { if (newtab != NULL) free(newtab); + fprintf(stderr, "%s: expand_tcbtab: out of memory\n", + progname); return 1; } for (i = tcbtabsize; i < 2 * tcbtabsize; ++i) @@ -763,6 +761,7 @@ int pid; return tcp; } } + fprintf(stderr, "%s: alloctcb: tcb table full\n", progname); return NULL; } @@ -2104,8 +2103,12 @@ trace() will we have the association of parent and child so that we know how to do clearbpt in the child. */ - if ((tcp = alloctcb(pid)) == NULL) { - fprintf(stderr, " [tcb table full]\n"); + if (nprocs == tcbtabsize && + expand_tcbtab()) + tcp = NULL; + else + tcp = alloctcb(pid); + if (tcp == NULL) { kill(pid, SIGKILL); /* XXX */ return 0; }