]> granicus.if.org Git - strace/commitdiff
2002-12-17 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@redhat.com>
Wed, 18 Dec 2002 04:16:10 +0000 (04:16 +0000)
committerRoland McGrath <roland@redhat.com>
Wed, 18 Dec 2002 04:16:10 +0000 (04:16 +0000)
* 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.

defs.h
process.c
strace.c

diff --git a/defs.h b/defs.h
index 43036852aef7dfed7174a544e136d417635ceb9e..c2f8ee6c38d74b05bca53185801680633a3d326c 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -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;
 
index e30fd1cf3540d9eeebe48cfe9c8ae604f1cf9e64..06ef7f203d1e60f55c1eaea84e67ee4fa2945f89 100644 (file)
--- a/process.c
+++ b/process.c
@@ -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;
        }
index 9f2a86109ad21db7454de285edff99b5d5e96570..9a4773fbb608117fcfd905d0cf27901ce1e04d01 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -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;