2002-12-17 Roland McGrath <roland@redhat.com>

* strace.c (tcbtab): Make this a pointer to pointers, not an array.
	(tcbtabsize): New variable.
	(main): Initialize them using dynamic allocation.
	(alloctcb, main): Use tcbtabsize in place of MAX_PROCS; indirect.
	(pid2tcb, cleanup): Likewise.
	[USE_PROCFS] (pollv): Make this a pointer, not an array; make static.
	(rebuild_pollv): Dynamically allocate the vector.
	* defs.h (tcbtab): Update decls.
	(MAX_PROCS): Macro removed, no more static limit on this.
	* process.c (fork_tcb): New function.
	(internal_clone, internal_fork): Use it instead of checking nprocs.
This commit is contained in:
Roland McGrath 2002-12-18 04:16:10 +00:00
parent 13f0b43041
commit ee9d435275
3 changed files with 71 additions and 36 deletions

15
defs.h
View File

@ -45,9 +45,6 @@
#define MAX_QUALS 2048 /* maximum number of syscalls, signals, etc. */
#endif
#endif
#ifndef MAX_PROCS
#define MAX_PROCS 64 /* maximum number of processes tracable */
#endif
#ifndef DEFAULT_STRLEN
#define DEFAULT_STRLEN 32 /* default maximum # of bytes printed in
`printstr', change with `-s' switch */
@ -90,7 +87,7 @@
# if defined(X86_64)
# define LINUX_X86_64
# endif
#endif
#endif
#if defined(SVR4) || defined(FREEBSD)
#define USE_PROCFS
@ -186,8 +183,8 @@ extern int ptrace();
#ifdef X86_64
#undef SUPPORTED_PERSONALITIES
#define SUPPORTED_PERSONALITIES 2
#endif
#endif
#ifdef SVR4
#ifdef HAVE_MP_PROCFS
extern int mp_ioctl (int f, int c, void *a, int s);
@ -216,7 +213,7 @@ extern int mp_ioctl (int f, int c, void *a, int s);
#else
#define IOCTL ioctl
#define IOCTL_STATUS(t) ioctl (t->pfd, PIOCSTATUS, &t->status)
#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWSTOP, &t->status)
#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWSTOP, &t->status)
#define PR_WHY pr_why
#define PR_WHAT pr_what
#define PR_REG pr_reg
@ -355,13 +352,13 @@ struct xlat {
#define TRACE_PROCESS 010 /* Trace process-related syscalls. */
#define TRACE_SIGNAL 020 /* Trace signal-related syscalls. */
extern struct tcb tcbtab[];
extern struct tcb **tcbtab;
extern int qual_flags[];
extern int debug, followfork, followvfork;
extern int rflag, tflag, dtime, cflag, xflag, qflag;
extern int acolumn;
extern char *outfname;
extern int nprocs;
extern unsigned int nprocs, tcbtabsize;
extern int max_strlen;
extern struct tcb *tcp_last;

View File

@ -368,6 +368,40 @@ struct tcb *tcp;
return 0;
}
/* 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
fork_tcb(struct tcb *tcp)
{
if (nprocs == tcbtabsize) {
/* Allocate some more TCBs and expand the table.
We don't want to relocate the TCBs because our
callers have pointers and it would be a pain.
So tcbtab is a table of pointers. Since we never
free the TCBs, we allocate a single chunk of many. */
struct tcb **newtab = (struct tcb **)
realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
sizeof *newtcbs);
int i;
if (newtab == NULL || newtcbs == NULL) {
if (newtab != NULL)
free(newtab);
tcp->flags &= ~TCB_FOLLOWFORK;
fprintf(stderr, "sys_fork: tcb table full\n");
return 1;
}
for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
newtab[i] = &newtcbs[i - tcbtabsize];
tcbtabsize *= 2;
tcbtab = newtab;
}
tcp->flags |= TCB_FOLLOWFORK;
return 0;
}
#ifdef USE_PROCFS
int
@ -414,13 +448,8 @@ struct tcb *tcp;
return 0;
if (!followfork)
return 0;
if (nprocs == MAX_PROCS) {
tcp->flags &= ~TCB_FOLLOWFORK;
fprintf(stderr, "sys_fork: tcb table full\n");
if (fork_tcb(tcp))
return 0;
}
else
tcp->flags |= TCB_FOLLOWFORK;
if (syserror(tcp))
return 0;
if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
@ -649,14 +678,8 @@ struct tcb *tcp;
if (entering(tcp)) {
if (!followfork)
return 0;
if (nprocs == MAX_PROCS) {
tcp->flags &= ~TCB_FOLLOWFORK;
fprintf(stderr, "sys_fork: tcb table full\n");
if (fork_tcb(tcp))
return 0;
}
tcp->flags |= TCB_FOLLOWFORK;
if (setbpt(tcp) < 0)
return 0;
} else {
@ -729,12 +752,8 @@ struct tcb *tcp;
if (entering(tcp)) {
if (!followfork || dont_follow)
return 0;
if (nprocs == MAX_PROCS) {
tcp->flags &= ~TCB_FOLLOWFORK;
fprintf(stderr, "sys_fork: tcb table full\n");
if (fork_tcb(tcp))
return 0;
}
tcp->flags |= TCB_FOLLOWFORK;
if (setbpt(tcp) < 0)
return 0;
}

View File

@ -78,8 +78,8 @@ int acolumn = DEFAULT_ACOLUMN;
int max_strlen = DEFAULT_STRLEN;
char *outfname = NULL;
FILE *outf;
struct tcb tcbtab[MAX_PROCS];
int nprocs;
struct tcb **tcbtab;
unsigned int nprocs, tcbtabsize;
char *progname;
extern char version[];
extern char **environ;
@ -105,7 +105,7 @@ static int interrupted;
static struct tcb *pfd2tcb P((int pfd));
static void reaper P((int sig));
static void rebuild_pollv P((void));
struct pollfd pollv[MAX_PROCS];
static struct pollfd *pollv;
#ifndef HAVE_POLLABLE_PROCFS
@ -184,6 +184,13 @@ char *argv[];
static char buf[BUFSIZ];
/* Allocate the initial tcbtab. */
tcbtabsize = argc; /* Surely enough for all -p args. */
tcbtab = (struct tcb **) malloc (tcbtabsize * sizeof tcbtab[0]);
tcbtab[0] = (struct tcb *) calloc (tcbtabsize, sizeof *tcbtab[0]);
for (tcp = tcbtab[0]; tcp < &tcbtab[0][tcbtabsize]; ++tcp)
tcbtab[tcp - tcbtab[0]] = &tcbtab[0][tcp - tcbtab[0]];
progname = argv[0];
outf = stderr;
interactive = 1;
@ -358,7 +365,8 @@ char *argv[];
else
qflag = 1;
for (c = 0, tcp = tcbtab; c < MAX_PROCS; c++, tcp++) {
for (c = 0; c < tcbtabsize; c++) {
tcp = tcbtab[c];
/* Reinitialize the output since it may have changed. */
tcp->outf = outf;
if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED))
@ -596,7 +604,8 @@ int pid;
int i;
struct tcb *tcp;
for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
for (i = 0; i < tcbtabsize; i++) {
tcp = tcbtab[i];
if ((tcp->flags & TCB_INUSE) == 0) {
tcp->pid = pid;
tcp->parent = NULL;
@ -930,7 +939,8 @@ int pid;
int i;
struct tcb *tcp;
for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
for (i = 0; i < tcbtabsize; i++) {
tcp = tcbtab[i];
if (pid && tcp->pid != pid)
continue;
if (tcp->flags & TCB_INUSE)
@ -948,7 +958,7 @@ int pfd;
int i;
struct tcb *tcp;
for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
for (i = 0, tcp = tcbtab; i < tcbtabsize; i++, tcp++) {
if (tcp->pfd != pfd)
continue;
if (tcp->flags & TCB_INUSE)
@ -1167,7 +1177,8 @@ cleanup()
int i;
struct tcb *tcp;
for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
for (i = 0; i < tcbtabsize; i++) {
tcp = tcbtab[i];
if (!(tcp->flags & TCB_INUSE))
continue;
if (debug)
@ -1255,7 +1266,15 @@ rebuild_pollv()
int i, j;
struct tcb *tcp;
for (i = j = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) {
if (pollv != NULL)
free (pollv);
pollv = (struct poll *) malloc(nprocs * sizeof pollv[0]);
if (pollv == NULL) {
fprintf(stderr, "strace: out of memory for poll vector\n");
exit(1);
}
for (i = j = 0, tcp = tcbtab; i < tcbtabsize; i++, tcp++) {
if (!(tcp->flags & TCB_INUSE))
continue;
pollv[j].fd = tcp->pfd;