]> granicus.if.org Git - strace/commitdiff
2006-12-21 Dmitry V. Levin <ldv@altlinux.org>
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 21 Dec 2006 21:15:04 +0000 (21:15 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 21 Dec 2006 21:15:04 +0000 (21:15 +0000)
Move counts code to separate file.
* count.c: New file.
* Makefile.am (strace_SOURCES): Add count.c.
* syscall.c (call_counts, countv, counts, shortest, time_cmp,
syscall_cmp, count_cmp, sortfun, overhead, set_sortby,
set_overhead, call_summary_pers, call_summary): Move to count.c
* count.c (count_syscall): New function.
* defs.h (count_syscall): Declare it.
* syscall.c (trace_syscall): Use it.

ChangeLog
Makefile.am
count.c [new file with mode: 0644]
defs.h
syscall.c

index fa98cb5bea099be2163612939fa19189b0184af9..32dd59243e2ad679de2099e22be486b5e27f8d55 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-12-21  Dmitry V. Levin <ldv@altlinux.org>
+
+       Move counts code to separate file.
+       * count.c: New file.
+       * Makefile.am (strace_SOURCES): Add count.c.
+       * syscall.c (call_counts, countv, counts, shortest, time_cmp,
+       syscall_cmp, count_cmp, sortfun, overhead, set_sortby,
+       set_overhead, call_summary_pers, call_summary): Move to count.c
+       * count.c (count_syscall): New function.
+       * defs.h (count_syscall): Declare it.
+       * syscall.c (trace_syscall): Use it.
+
 2006-12-20  Dmitry V. Levin <ldv@altlinux.org>
 
        * syscall.c (internal_syscall): Change conditions for internal_exit,
index 7b44f1e65f6a23539012680d482a7b2edcae0f5d..a9972fe2a22c81aee02cdabb0ae05e7d61699d7e 100644 (file)
@@ -12,7 +12,7 @@ ARCH          = @arch@
 AM_CFLAGS = $(WARNFLAGS)
 INCLUDES = -I$(OS)/$(ARCH) -I$(srcdir)/$(OS)/$(ARCH) -I$(OS) -I$(srcdir)/$(OS)
 
-strace_SOURCES = strace.c syscall.c util.c desc.c file.c ipc.c \
+strace_SOURCES = strace.c syscall.c count.c util.c desc.c file.c ipc.c \
                 io.c ioctl.c mem.c net.c process.c bjm.c quota.c \
                 resource.c signal.c sock.c system.c term.c time.c \
                 proc.c stream.c
diff --git a/count.c b/count.c
new file mode 100644 (file)
index 0000000..5c285fb
--- /dev/null
+++ b/count.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
+ * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
+ * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
+ * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
+ * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *                     Linux for s390 port by D.J. Barrow
+ *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
+ * Copyright (c) 2004 Roland McGrath <roland@redhat.com>
+ * Copyright (c) 2006 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *     $Id$
+ */
+
+#include "defs.h"
+
+struct call_counts {
+       struct timeval time;
+       int calls, errors;
+};
+
+static struct call_counts *countv[SUPPORTED_PERSONALITIES];
+#define counts (countv[current_personality])
+
+static struct timeval shortest = { 1000000, 0 };
+
+int
+count_syscall(struct tcb *tcp, struct timeval *tv)
+{
+       tcp->flags &= ~TCB_INSYSCALL;
+       if (tcp->scno < 0 || tcp->scno >= nsyscalls)
+               return 0;
+
+       if (!counts)
+       {
+               counts = calloc(nsyscalls, sizeof(*counts));
+               if (!counts)
+               {
+                       fprintf(stderr,
+                               "strace: out of memory for call counts\n");
+                       exit(1);
+               }
+       }
+
+       counts[tcp->scno].calls++;
+       if (tcp->u_error)
+               counts[tcp->scno].errors++;
+
+       tv_sub(tv, tv, &tcp->etime);
+#ifdef LINUX
+       if (tv_cmp(tv, &tcp->dtime) > 0)
+       {
+               static struct timeval one_tick;
+
+               if (one_tick.tv_usec == 0)
+               {
+                       /* Initialize it.  */
+                       struct itimerval it;
+
+                       memset(&it, 0, sizeof it);
+                       it.it_interval.tv_usec = 1;
+                       setitimer(ITIMER_REAL, &it, NULL);
+                       getitimer(ITIMER_REAL, &it);
+                       one_tick = it.it_interval;
+               }
+
+               if (tv_nz(&tcp->dtime))
+                       *tv = tcp->dtime;
+               else if (tv_cmp(tv, &one_tick) > 0)
+               {
+                       if (tv_cmp(&shortest, &one_tick) < 0)
+                               *tv = shortest;
+                       else
+                               *tv = one_tick;
+               }
+       }
+#endif /* LINUX */
+       if (tv_cmp(tv, &shortest) < 0)
+               shortest = *tv;
+       tv_add(&counts[tcp->scno].time, &counts[tcp->scno].time, tv);
+
+       return 0;
+}
+
+static int
+time_cmp(void *a, void *b)
+{
+       return -tv_cmp(&counts[*((int *) a)].time,
+                      &counts[*((int *) b)].time);
+}
+
+static int
+syscall_cmp(void *a, void *b)
+{
+       return strcmp(sysent[*((int *) a)].sys_name,
+                     sysent[*((int *) b)].sys_name);
+}
+
+static int
+count_cmp(void *a, void *b)
+{
+       int     m = counts[*((int *) a)].calls;
+       int     n = counts[*((int *) b)].calls;
+
+       return (m < n) ? 1 : (m > n) ? -1 : 0;
+}
+
+static int (*sortfun)();
+static struct timeval overhead = { -1, -1 };
+
+void
+set_sortby(char *sortby)
+{
+       if (strcmp(sortby, "time") == 0)
+               sortfun = time_cmp;
+       else if (strcmp(sortby, "calls") == 0)
+               sortfun = count_cmp;
+       else if (strcmp(sortby, "name") == 0)
+               sortfun = syscall_cmp;
+       else if (strcmp(sortby, "nothing") == 0)
+               sortfun = NULL;
+       else
+       {
+               fprintf(stderr, "invalid sortby: `%s'\n", sortby);
+               exit(1);
+       }
+}
+
+void set_overhead(int n)
+{
+       overhead.tv_sec = n / 1000000;
+       overhead.tv_usec = n % 1000000;
+}
+
+static void
+call_summary_pers(FILE *outf)
+{
+       int     i, j;
+       int     call_cum, error_cum;
+       struct timeval tv_cum, dtv;
+       double  percent;
+       char   *dashes = "-------------------------";
+       char    error_str[16];
+
+       int    *sorted_count = calloc(sizeof(int), nsyscalls);
+
+       call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
+       if (overhead.tv_sec == -1)
+       {
+               tv_mul(&overhead, &shortest, 8);
+               tv_div(&overhead, &overhead, 10);
+       }
+       for (i = 0; i < nsyscalls; i++)
+       {
+               sorted_count[i] = i;
+               if (counts == NULL || counts[i].calls == 0)
+                       continue;
+               tv_mul(&dtv, &overhead, counts[i].calls);
+               tv_sub(&counts[i].time, &counts[i].time, &dtv);
+               call_cum += counts[i].calls;
+               error_cum += counts[i].errors;
+               tv_add(&tv_cum, &tv_cum, &counts[i].time);
+       }
+       if (counts && sortfun)
+               qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun);
+       fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
+               "% time", "seconds", "usecs/call",
+               "calls", "errors", "syscall");
+       fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
+               dashes, dashes, dashes, dashes, dashes, dashes);
+       if (counts)
+       {
+               for (i = 0; i < nsyscalls; i++)
+               {
+                       j = sorted_count[i];
+                       if (counts[j].calls == 0)
+                               continue;
+                       tv_div(&dtv, &counts[j].time, counts[j].calls);
+                       if (counts[j].errors)
+                               sprintf(error_str, "%d", counts[j].errors);
+                       else
+                               error_str[0] = '\0';
+                       percent = (100.0 * tv_float(&counts[j].time)
+                                  / tv_float(&tv_cum));
+                       fprintf(outf, "%6.2f %4ld.%06ld %11ld %9d %9.9s %s\n",
+                               percent, (long) counts[j].time.tv_sec,
+                               (long) counts[j].time.tv_usec,
+                               (long) 1000000 * dtv.tv_sec + dtv.tv_usec,
+                               counts[j].calls,
+                               error_str, sysent[j].sys_name);
+               }
+       }
+       free(sorted_count);
+
+       fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
+               dashes, dashes, dashes, dashes, dashes, dashes);
+       if (error_cum)
+               sprintf(error_str, "%d", error_cum);
+       else
+               error_str[0] = '\0';
+       fprintf(outf, "%6.6s %4ld.%06ld %11.11s %9d %9.9s %s\n",
+               "100.00", (long) tv_cum.tv_sec, (long) tv_cum.tv_usec, "",
+               call_cum, error_str, "total");
+}
+
+void
+call_summary(FILE *outf)
+{
+       int     i, old_pers = current_personality;
+
+       for (i = 0; i < SUPPORTED_PERSONALITIES; ++i)
+       {
+               if (!countv[i])
+                       continue;
+
+               if (current_personality != i)
+                       set_personality(i);
+               if (i)
+                       fprintf(outf,
+                               "System call usage summary for %u bit mode:\n",
+                               personality_wordsize[current_personality] * 8);
+               call_summary_pers(outf);
+       }
+
+       if (old_pers != current_personality)
+               set_personality(old_pers);
+}
diff --git a/defs.h b/defs.h
index 87569080d85595707a45707a4371bedde3414963..beef2a77a165f28be2bb353955f465380802ddb5 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -438,6 +438,7 @@ extern void qualify P((char *));
 extern int get_scno P((struct tcb *));
 extern long known_scno P((struct tcb *));
 extern int trace_syscall P((struct tcb *));
+extern int count_syscall P((struct tcb *, struct timeval *));
 extern void printxval P((const struct xlat *, int, const char *));
 extern int printargs P((struct tcb *));
 extern int addflags P((const struct xlat *, int));
index 6bc0618b6ebfa6453634629c3d4247326bcc2f82..dabdd76f16a25cada8eb63311bf114e9857abbf7 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -249,16 +249,6 @@ set_personality(int personality)
 }
 
 
-struct call_counts {
-       struct timeval time;
-       int calls, errors;
-};
-
-static struct call_counts *countv[SUPPORTED_PERSONALITIES];
-#define counts (countv[current_personality])
-
-static struct timeval shortest = { 1000000, 0 };
-
 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
 
 static const struct qual_options {
@@ -2240,8 +2230,7 @@ struct tcb *tcp;
 }
 
 int
-trace_syscall(tcp)
-struct tcb *tcp;
+trace_syscall(struct tcb *tcp)
 {
        int sys_res;
        struct timeval tv;
@@ -2282,50 +2271,8 @@ struct tcb *tcp;
                        tprintf(" resumed> ");
                }
 
-               if (cflag && tcp->scno < nsyscalls && tcp->scno >= 0) {
-                       if (counts == NULL) {
-                               counts = calloc(sizeof *counts, nsyscalls);
-                               if (counts == NULL) {
-                                       fprintf(stderr, "\
-strace: out of memory for call counts\n");
-                                       exit(1);
-                               }
-                       }
-
-                       counts[tcp->scno].calls++;
-                       if (tcp->u_error)
-                               counts[tcp->scno].errors++;
-                       tv_sub(&tv, &tv, &tcp->etime);
-#ifdef LINUX
-                       if (tv_cmp(&tv, &tcp->dtime) > 0) {
-                               static struct timeval one_tick;
-                               if (one_tick.tv_usec == 0) {
-                                       /* Initialize it.  */
-                                       struct itimerval it;
-                                       memset(&it, 0, sizeof it);
-                                       it.it_interval.tv_usec = 1;
-                                       setitimer(ITIMER_REAL, &it, NULL);
-                                       getitimer(ITIMER_REAL, &it);
-                                       one_tick = it.it_interval;
-                               }
-
-                               if (tv_nz(&tcp->dtime))
-                                       tv = tcp->dtime;
-                               else if (tv_cmp(&tv, &one_tick) > 0) {
-                                       if (tv_cmp(&shortest, &one_tick) < 0)
-                                               tv = shortest;
-                                       else
-                                               tv = one_tick;
-                               }
-                       }
-#endif /* LINUX */
-                       if (tv_cmp(&tv, &shortest) < 0)
-                               shortest = tv;
-                       tv_add(&counts[tcp->scno].time,
-                               &counts[tcp->scno].time, &tv);
-                       tcp->flags &= ~TCB_INSYSCALL;
-                       return 0;
-               }
+               if (cflag)
+                       return count_syscall(tcp, &tv);
 
                if (tcp->scno >= nsyscalls || tcp->scno < 0
                    || (qual_flags[tcp->scno] & QUAL_RAW))
@@ -2650,149 +2597,3 @@ struct tcb *tcp;
        return 0;
 }
 #endif /* SUNOS4 */
-
-static int
-time_cmp(a, b)
-void *a;
-void *b;
-{
-       return -tv_cmp(&counts[*((int *) a)].time, &counts[*((int *) b)].time);
-}
-
-static int
-syscall_cmp(a, b)
-void *a;
-void *b;
-{
-       return strcmp(sysent[*((int *) a)].sys_name,
-               sysent[*((int *) b)].sys_name);
-}
-
-static int
-count_cmp(a, b)
-void *a;
-void *b;
-{
-       int m = counts[*((int *) a)].calls, n = counts[*((int *) b)].calls;
-
-       return (m < n) ? 1 : (m > n) ? -1 : 0;
-}
-
-static int (*sortfun)();
-static struct timeval overhead = { -1, -1 };
-
-void
-set_sortby(sortby)
-char *sortby;
-{
-       if (strcmp(sortby, "time") == 0)
-               sortfun = time_cmp;
-       else if (strcmp(sortby, "calls") == 0)
-               sortfun = count_cmp;
-       else if (strcmp(sortby, "name") == 0)
-               sortfun = syscall_cmp;
-       else if (strcmp(sortby, "nothing") == 0)
-               sortfun = NULL;
-       else {
-               fprintf(stderr, "invalid sortby: `%s'\n", sortby);
-               exit(1);
-       }
-}
-
-void set_overhead(n)
-int n;
-{
-       overhead.tv_sec = n / 1000000;
-       overhead.tv_usec = n % 1000000;
-}
-
-static void
-call_summary_pers(FILE *outf)
-{
-       int i, j;
-       int call_cum, error_cum;
-       struct timeval tv_cum, dtv;
-       double percent;
-       char *dashes = "-------------------------";
-       char error_str[16];
-
-       int *sorted_count = malloc(nsyscalls * sizeof(int));
-
-       call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
-       if (overhead.tv_sec == -1) {
-               tv_mul(&overhead, &shortest, 8);
-               tv_div(&overhead, &overhead, 10);
-       }
-       for (i = 0; i < nsyscalls; i++) {
-               sorted_count[i] = i;
-               if (counts == NULL || counts[i].calls == 0)
-                       continue;
-               tv_mul(&dtv, &overhead, counts[i].calls);
-               tv_sub(&counts[i].time, &counts[i].time, &dtv);
-               call_cum += counts[i].calls;
-               error_cum += counts[i].errors;
-               tv_add(&tv_cum, &tv_cum, &counts[i].time);
-       }
-       if (counts && sortfun)
-               qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun);
-       fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
-               "% time", "seconds", "usecs/call",
-               "calls", "errors", "syscall");
-       fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
-               dashes, dashes, dashes, dashes, dashes, dashes);
-       if (counts) {
-               for (i = 0; i < nsyscalls; i++) {
-                       j = sorted_count[i];
-                       if (counts[j].calls == 0)
-                               continue;
-                       tv_div(&dtv, &counts[j].time, counts[j].calls);
-                       if (counts[j].errors)
-                               sprintf(error_str, "%d", counts[j].errors);
-                       else
-                               error_str[0] = '\0';
-                       percent = (100.0 * tv_float(&counts[j].time)
-                                  / tv_float(&tv_cum));
-                       fprintf(outf, "%6.2f %4ld.%06ld %11ld %9d %9.9s %s\n",
-                               percent, (long) counts[j].time.tv_sec,
-                               (long) counts[j].time.tv_usec,
-                               (long) 1000000 * dtv.tv_sec + dtv.tv_usec,
-                               counts[j].calls,
-                               error_str, sysent[j].sys_name);
-               }
-       }
-       free(sorted_count);
-
-       fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
-               dashes, dashes, dashes, dashes, dashes, dashes);
-       if (error_cum)
-               sprintf(error_str, "%d", error_cum);
-       else
-               error_str[0] = '\0';
-       fprintf(outf, "%6.6s %4ld.%06ld %11.11s %9d %9.9s %s\n",
-               "100.00", (long) tv_cum.tv_sec, (long) tv_cum.tv_usec, "",
-               call_cum, error_str, "total");
-
-}
-
-void
-call_summary(FILE *outf)
-{
-       int     i, old_pers = current_personality;
-
-       for (i = 0; i < SUPPORTED_PERSONALITIES; ++i)
-       {
-               if (!countv[i])
-                       continue;
-
-               if (current_personality != i)
-                       set_personality(i);
-               if (i)
-                       fprintf(outf,
-                               "System call usage summary for %u bit mode:\n",
-                               personality_wordsize[current_personality] * 8);
-               call_summary_pers(outf);
-       }
-
-       if (old_pers != current_personality)
-               set_personality(old_pers);
-}