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-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.
+
2006-08-22 Roland McGrath <roland@redhat.com>
* ipc.c (sys_msgget, sys_semget, sys_shmget): Show key values in hex.
if (nprocs == tcbtabsize) {
if (expand_tcbtab()) {
tcp->flags &= ~TCB_FOLLOWFORK;
- fprintf(stderr, "sys_fork: tcb table full\n");
+ return 1;
}
}
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);
}
}
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;
}
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;
}
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++;
}
default:
if ((tcp = alloctcb(pid)) == NULL) {
- fprintf(stderr, "tcb table full\n");
cleanup();
exit(1);
}
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)
return tcp;
}
}
+ fprintf(stderr, "%s: alloctcb: tcb table full\n", progname);
return NULL;
}
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;
}