Two cleanups: tcb table expansion failure is not really a survivable
event, we do not have any viable way to continue. No wonder most
places where that is detected have FIXMEs.
It's way simpler to treat as fatal failure, and handle it inside
tcb table expansion finctions.
Second cleanup: tidy up haphazard locations of a few externs.
* defs.h: Change return type of expand_tcbtab() to void.
Declare change_syscall().
* process.c: Change all callsites of alloctcb(), alloc_tcb() and
fork_tcb(), removing now-redundant error checks.
(fork_tcb): Change return type to void - it can't fail now.
* strace.c: Move extern declarations out of function bodies.
Change all callsites of alloctcb(), alloc_tcb() and
fork_tcb(), removing now-redundant error checks.
(expand_tcbtab): Change return type to void - it can't fail now.
On failure to expand, print a message, clean up, and exit.
(alloc_tcb): On failure to expand, print a message, clean up, and exit.
* util.c (setbpt): Remove extern declaration from function body.
diff --git a/ChangeLog b/ChangeLog
index e55baa9..8bedc90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
2009-01-17 Denys Vlasenko <dvlasenk@redhat.com>
+ Two cleanups: tcb table expansion failure is not really a survivable
+ event, we do not have any viable way to continue. No wonder most
+ places where that is detected have FIXMEs.
+ It's way simpler to treat as fatal failure, and handle it inside
+ tcb table expansion finctions.
+ Second cleanup: tidy up haphazard locations of a few externs.
+
+ * defs.h: Change return type of expand_tcbtab() to void.
+ Declare change_syscall().
+ * process.c: Change all callsites of alloctcb(), alloc_tcb() and
+ fork_tcb(), removing now-redundant error checks.
+ (fork_tcb): Change return type to void - it can't fail now.
+ * strace.c: Move extern declarations out of function bodies.
+ Change all callsites of alloctcb(), alloc_tcb() and
+ fork_tcb(), removing now-redundant error checks.
+ (expand_tcbtab): Change return type to void - it can't fail now.
+ On failure to expand, print a message, clean up, and exit.
+ (alloc_tcb): On failure to expand, print a message, clean up, and exit.
+ * util.c (setbpt): Remove extern declaration from function body.
+
+2009-01-17 Denys Vlasenko <dvlasenk@redhat.com>
+
* defs.h: Update a comment. No code changes.
* strace.c (handle_stopped_tcbs): Discard all execve stops
and clear TCB_WAITEXECVE bit.
diff --git a/defs.h b/defs.h
index d2315e2..ce9b12f 100644
--- a/defs.h
+++ b/defs.h
@@ -481,7 +481,7 @@
extern struct tcb *alloc_tcb P((int, int));
extern struct tcb *pid2tcb P((int));
extern void droptcb P((struct tcb *));
-extern int expand_tcbtab P((void));
+extern void expand_tcbtab P((void));
#define alloctcb(pid) alloc_tcb((pid), 1)
@@ -535,6 +535,7 @@
extern void tprint_open_modes P((struct tcb *, mode_t));
extern int is_restart_error P((struct tcb *));
+extern int change_syscall P((struct tcb *, int));
#ifdef LINUX
extern int internal_clone P((struct tcb *));
#endif
diff --git a/process.c b/process.c
index 7107361..bd80667 100644
--- a/process.c
+++ b/process.c
@@ -487,25 +487,19 @@
/* TCP is creating a child we want to follow.
If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
-static int
+static void
fork_tcb(struct tcb *tcp)
{
- if (nprocs == tcbtabsize) {
- if (expand_tcbtab()) {
- tcp->flags &= ~TCB_FOLLOWFORK;
- return 1;
- }
- }
+ if (nprocs == tcbtabsize)
+ expand_tcbtab();
tcp->flags |= TCB_FOLLOWFORK;
- return 0;
}
#ifdef USE_PROCFS
int
-sys_fork(tcp)
-struct tcb *tcp;
+sys_fork(struct tcb *tcp)
{
if (exiting(tcp) && !syserror(tcp)) {
if (getrval2(tcp)) {
@@ -551,12 +545,10 @@
return 0;
if (!followfork)
return 0;
- if (fork_tcb(tcp))
- return 0;
+ fork_tcb(tcp);
if (syserror(tcp))
return 0;
- if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
- return 0;
+ tcpchild = alloctcb(tcp->u_rval);
if (proc_open(tcpchild, 2) < 0)
droptcb(tcpchild);
}
@@ -706,9 +698,7 @@
}
int
-change_syscall(tcp, new)
-struct tcb *tcp;
-int new;
+change_syscall(struct tcb *tcp, int new)
{
#if defined(LINUX)
#if defined(I386)
@@ -758,9 +748,12 @@
#elif defined(IA64)
if (ia32) {
switch (new) {
- case 2: break; /* x86 SYS_fork */
- case SYS_clone: new = 120; break;
- default:
+ case 2:
+ break; /* x86 SYS_fork */
+ case SYS_clone:
+ new = 120;
+ break;
+ default:
fprintf(stderr, "%s: unexpected syscall %d\n",
__FUNCTION__, new);
return -1;
@@ -892,8 +885,7 @@
if (entering(tcp)) {
if (!followfork)
return 0;
- if (fork_tcb(tcp))
- return 0;
+ fork_tcb(tcp);
if (setbpt(tcp) < 0)
return 0;
} else {
@@ -924,12 +916,8 @@
}
else
#endif
- if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
- if (bpt)
- clearbpt(tcp);
- kill(pid, SIGKILL); /* XXX */
- return 0;
- }
+ fork_tcb(tcp);
+ tcpchild = alloctcb(pid);
#ifndef CLONE_PTRACE
/* Attach to the new child */
@@ -1042,8 +1030,7 @@
if (entering(tcp)) {
if (!followfork || dont_follow)
return 0;
- if (fork_tcb(tcp))
- return 0;
+ fork_tcb(tcp);
if (setbpt(tcp) < 0)
return 0;
}
@@ -1059,10 +1046,8 @@
return 0;
pid = tcp->u_rval;
- if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
- kill(pid, SIGKILL); /* XXX */
- return 0;
- }
+ fork_tcb(tcp);
+ tcpchild = alloctcb(pid);
#ifdef LINUX
#ifdef HPPA
/* The child must have run before it can be attached. */
diff --git a/strace.c b/strace.c
index 8c387f9..40d1e8d 100644
--- a/strace.c
+++ b/strace.c
@@ -78,6 +78,8 @@
#endif
#endif
extern char **environ;
+extern int optind;
+extern char *optarg;
int debug = 0, followfork = 0;
@@ -436,13 +438,7 @@
(char *) 1, 0) < 0)
++nerr;
else if (tid != tcbtab[tcbi]->pid) {
- if (nprocs == tcbtabsize &&
- expand_tcbtab())
- tcp = NULL;
- else
- tcp = alloctcb(tid);
- if (tcp == NULL)
- exit(1);
+ tcp = alloctcb(tid);
tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD|TCB_CLONE_DETACHED|TCB_FOLLOWFORK;
tcbtab[tcbi]->nchildren++;
tcbtab[tcbi]->nclone_threads++;
@@ -675,10 +671,6 @@
/* We are the tracer. */
tcp = alloctcb(daemonized_tracer ? getppid() : pid);
- if (tcp == NULL) {
- cleanup();
- exit(1);
- }
if (daemonized_tracer) {
/* We want subsequent startup_attach() to attach to it. */
tcp->flags |= TCB_ATTACHED;
@@ -695,8 +687,6 @@
int
main(int argc, char *argv[])
{
- extern int optind;
- extern char *optarg;
struct tcb *tcp;
int c, pid = 0;
int optF = 0;
@@ -708,11 +698,11 @@
/* Allocate the initial tcbtab. */
tcbtabsize = argc; /* Surely enough for all -p args. */
- if ((tcbtab = calloc (tcbtabsize, sizeof tcbtab[0])) == NULL) {
+ if ((tcbtab = calloc(tcbtabsize, sizeof tcbtab[0])) == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
- if ((tcbtab[0] = calloc (tcbtabsize, sizeof tcbtab[0][0])) == NULL) {
+ if ((tcbtab[0] = calloc(tcbtabsize, sizeof tcbtab[0][0])) == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
@@ -807,11 +797,7 @@
fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname);
break;
}
- if ((tcp = alloc_tcb(pid, 0)) == NULL) {
- fprintf(stderr, "%s: out of memory\n",
- progname);
- exit(1);
- }
+ tcp = alloc_tcb(pid, 0);
tcp->flags |= TCB_ATTACHED;
pflag_seen++;
break;
@@ -979,8 +965,8 @@
exit(exit_code);
}
-int
-expand_tcbtab()
+void
+expand_tcbtab(void)
{
/* Allocate some more TCBs and expand the table.
We don't want to relocate the TCBs because our
@@ -993,27 +979,26 @@
sizeof *newtcbs);
int i;
if (newtab == NULL || newtcbs == NULL) {
- if (newtab != NULL)
- free(newtab);
fprintf(stderr, "%s: expand_tcbtab: out of memory\n",
progname);
- return 1;
+ cleanup();
+ exit(1);
}
for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
newtab[i] = &newtcbs[i - tcbtabsize];
tcbtabsize *= 2;
tcbtab = newtab;
-
- return 0;
}
-
struct tcb *
alloc_tcb(int pid, int command_options_parsed)
{
int i;
struct tcb *tcp;
+ if (nprocs == tcbtabsize)
+ expand_tcbtab();
+
for (i = 0; i < tcbtabsize; i++) {
tcp = tcbtab[i];
if ((tcp->flags & TCB_INUSE) == 0) {
@@ -1036,15 +1021,14 @@
return tcp;
}
}
- fprintf(stderr, "%s: alloc_tcb: tcb table full\n", progname);
- return NULL;
+ fprintf(stderr, "%s: bug in alloc_tcb\n", progname);
+ cleanup();
+ exit(1);
}
#ifdef USE_PROCFS
int
-proc_open(tcp, attaching)
-struct tcb *tcp;
-int attaching;
+proc_open(struct tcb *tcp, int attaching)
{
char proc[32];
long arg;
@@ -2369,15 +2353,7 @@
will we have the association of parent and
child so that we know how to do clearbpt
in the child. */
- if (nprocs == tcbtabsize &&
- expand_tcbtab())
- tcp = NULL;
- else
- tcp = alloctcb(pid);
- if (tcp == NULL) {
- kill(pid, SIGKILL); /* XXX */
- return NULL;
- }
+ tcp = alloctcb(pid);
tcp->flags |= TCB_ATTACHED | TCB_SUSPENDED;
if (!qflag)
fprintf(stderr, "\
diff --git a/util.c b/util.c
index 763ae84..affb167 100644
--- a/util.c
+++ b/util.c
@@ -1593,11 +1593,9 @@
#endif
int
-setbpt(tcp)
-struct tcb *tcp;
+setbpt(struct tcb *tcp)
{
static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone };
- extern int change_syscall(struct tcb *, int);
arg_setup_state state;
if (tcp->flags & TCB_BPTSET) {