From 7b54a7ae61d0eda798575f77d898a24dda7a0952 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 4 Jun 2004 01:50:45 +0000 Subject: [PATCH] 2004-06-03 Roland McGrath * strace.c (main) [LINUX]: Expand TCBTAB as necessary for threads attached. Attach threads only under -f. Set TCB_FOLLOWFORK in them. (expand_tcbtab): New function, broken out of ... * process.c (fork_tcb): ... here, call that. * defs.h: Declare expand_tcbtab. --- defs.h | 1 + process.c | 19 +------------------ strace.c | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/defs.h b/defs.h index 6d22d34f..95cd897b 100644 --- a/defs.h +++ b/defs.h @@ -413,6 +413,7 @@ extern char *xlookup P((struct xlat *, int)); extern struct tcb *alloctcb P((int)); extern struct tcb *pid2tcb P((int)); extern void droptcb P((struct tcb *)); +extern int expand_tcbtab P((void)); extern void set_sortby P((char *)); extern void set_overhead P((int)); diff --git a/process.c b/process.c index 038fc14e..77647256 100644 --- a/process.c +++ b/process.c @@ -402,27 +402,10 @@ 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); + if (expand_tcbtab()) { 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; diff --git a/strace.c b/strace.c index a8a1e400..5fc640d3 100644 --- a/strace.c +++ b/strace.c @@ -403,7 +403,7 @@ char *argv[]; # ifdef LINUX if (tcp->flags & TCB_CLONE_THREAD) continue; - { + if (followfork) { char procdir[MAXPATHLEN]; DIR *dir; sprintf(procdir, "/proc/%d/task", tcp->pid); @@ -424,13 +424,17 @@ char *argv[]; (char *) 1, 0) < 0) ++nerr; else if (tid != tcbtab[c]->pid) { - tcp = alloctcb(tid); + if (nprocs == tcbtabsize && + expand_tcbtab()) + tcp = NULL; + else + tcp = alloctcb(tid); if (tcp == NULL) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } - tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD|TCB_CLONE_DETACHED; + tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD|TCB_CLONE_DETACHED|TCB_FOLLOWFORK; tcbtab[c]->nchildren++; tcbtab[c]->nclone_threads++; tcbtab[c]->nclone_detached++; @@ -688,6 +692,33 @@ struct tcb *tcp; return; } +int +expand_tcbtab() +{ + /* 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); + return 1; + } + for (i = tcbtabsize; i < 2 * tcbtabsize; ++i) + newtab[i] = &newtcbs[i - tcbtabsize]; + tcbtabsize *= 2; + tcbtab = newtab; + + return 0; +} + + struct tcb * alloctcb(pid) int pid; -- 2.40.0