2006-03-29 Dmitry V. Levin <ldv@altlinux.org>
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/strace.c b/strace.c
index 1553fb5..0da34ab 100644
--- a/strace.c
+++ b/strace.c
@@ -442,11 +442,8 @@
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 @@
}
default:
if ((tcp = alloctcb(pid)) == NULL) {
- fprintf(stderr, "tcb table full\n");
cleanup();
exit(1);
}
@@ -725,6 +721,8 @@
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 @@
return tcp;
}
}
+ fprintf(stderr, "%s: alloctcb: tcb table full\n", progname);
return NULL;
}
@@ -2104,8 +2103,12 @@
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;
}