[PATCH]count signals too with -c option

Shen Feng shen at cn.fujitsu.com
Fri Aug 3 02:19:14 UTC 2007


Hello,

I add support for count signals too with -c option.
Now only the -S option is supported.
Without -S option, the signal is sorted by signal number.
With -S name option, the signal is sorted by signal name.
With -S calls option, the signal is sorted by received numbers.

[fenian at shenf strace-4.5.15.new]$ ./strace -c sleep 100
Process 6252 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
   nan    0.000000           0         5         5 restart_syscall
   nan    0.000000           0         1           read
   nan    0.000000           0         3           open
   nan    0.000000           0         3           close
   nan    0.000000           0         1           execve
   nan    0.000000           0         1         1 access
   nan    0.000000           0         3           brk
   nan    0.000000           0         1           munmap
   nan    0.000000           0         2           mprotect
   nan    0.000000           0         1         1 nanosleep
   nan    0.000000           0         8           mmap2
   nan    0.000000           0         3           fstat64
   nan    0.000000           0         1           set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    33         7 total
 recieves signal
--------- ----------------
        2 SIGCHLD
        3 SIGCONT
        1 SIGRT_32
--------- ----------------
        6 total

[fenian at shenf strace-4.5.15.new]$ ./strace -c -S name sleep 100
Process 6407 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           close
100.00    0.000185         185         1           execve
  0.00    0.000000           0         3           fstat64
  0.00    0.000000           0         8           mmap2
  0.00    0.000000           0         2           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         1         1 nanosleep
  0.00    0.000000           0         3           open
  0.00    0.000000           0         1           read
  0.00    0.000000           0         5         5 restart_syscall
  0.00    0.000000           0         1           set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00    0.000185                    33         7 total
 recieves signal
--------- ----------------
        2 SIGCHLD
        3 SIGCONT
        1 SIGRT_32
--------- ----------------
        6 total
[fenian at shenf strace-4.5.15.new]$ ./strace -c -S calls sleep 100
Process 6530 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
   nan    0.000000           0         8           mmap2
   nan    0.000000           0         5         5 restart_syscall
   nan    0.000000           0         3           open
   nan    0.000000           0         3           close
   nan    0.000000           0         3           brk
   nan    0.000000           0         3           fstat64
   nan    0.000000           0         2           mprotect
   nan    0.000000           0         1           read
   nan    0.000000           0         1           execve
   nan    0.000000           0         1         1 access
   nan    0.000000           0         1           munmap
   nan    0.000000           0         1         1 nanosleep
   nan    0.000000           0         1           set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    33         7 total
 recieves signal
--------- ----------------
        3 SIGCONT
        2 SIGCHLD
        1 SIGRT_32
--------- ----------------
        6 total


The following is the patch.

Signed-off-by: "Shen Feng" <shen at cn.fujitsu.com>

diff -Nur strace-4.5.15/count.c strace-4.5.15.new/count.c
--- strace-4.5.15/count.c	2006-12-22 05:15:04.000000000 +0800
+++ strace-4.5.15.new/count.c	2007-08-03 09:16:38.000000000 +0800
@@ -45,6 +45,18 @@
 static struct call_counts *countv[SUPPORTED_PERSONALITIES];
 #define counts (countv[current_personality])

+struct signal_counts {
+	int calls;
+};
+static struct signal_counts *sigcountv[SUPPORTED_PERSONALITIES];
+#define sigcounts (sigcountv[current_personality])
+
+#ifdef SIGRTMIN
+static int nsignals_max = __SIGRTMAX+1;
+#else /* SIGRTMIN */
+static int nsignals_max = nsignals;
+#endif
+
 static struct timeval shortest = { 1000000, 0 };

 int
@@ -105,6 +117,25 @@
 	return 0;
 }

+int count_signal(int sig)
+{
+	if (!sigcounts)
+	{
+		sigcounts = calloc(nsignals_max, sizeof(*sigcounts));
+		if (!sigcounts)
+		{
+			fprintf(stderr,
+				"strace: out of memory for call counts\n");
+			exit(1);
+		}
+	}
+	if (sig < nsignals_max)
+	{
+		sigcounts[sig].calls++;
+	}
+	return 0;
+}
+
 static int
 time_cmp(void *a, void *b)
 {
@@ -120,6 +151,13 @@
 }

 static int
+signal_cmp(void *a, void *b)
+{
+	return strcmp(signame(*((int *) a)),
+		      signame(*((int *) b)));
+}
+
+static int
 count_cmp(void *a, void *b)
 {
 	int     m = counts[*((int *) a)].calls;
@@ -128,20 +166,43 @@
 	return (m < n) ? 1 : (m > n) ? -1 : 0;
 }

+static int
+sig_count_cmp(void *a, void *b)
+{
+	int     m = sigcounts[*((int *) a)].calls;
+	int     n = sigcounts[*((int *) b)].calls;
+
+	return (m < n) ? 1 : (m > n) ? -1 : 0;
+}
+
+
 static int (*sortfun)();
+static int (*sig_sortfun)();
 static struct timeval overhead = { -1, -1 };

 void
 set_sortby(char *sortby)
 {
 	if (strcmp(sortby, "time") == 0)
+	{
 		sortfun = time_cmp;
+		sig_sortfun = NULL;
+	}
 	else if (strcmp(sortby, "calls") == 0)
+	{
 		sortfun = count_cmp;
+		sig_sortfun = sig_count_cmp;
+	}
 	else if (strcmp(sortby, "name") == 0)
+	{
 		sortfun = syscall_cmp;
+		sig_sortfun = signal_cmp;
+	}
 	else if (strcmp(sortby, "nothing") == 0)
+	{
 		sortfun = NULL;
+		sig_sortfun = NULL;
+	}
 	else
 	{
 		fprintf(stderr, "invalid sortby: `%s'\n", sortby);
@@ -226,6 +287,41 @@
 		call_cum, error_str, "total");
 }

+static void
+call_summary_signal_pers(FILE *outf)
+{
+	int	i, j;
+	char	*dashes = "-------------------------";
+	int	call_cum = 0;
+	int	*sorted_count = calloc(sizeof(int), nsignals_max);
+
+	fprintf(outf, "%9.9s %s\n", "recieves", "signal");
+	fprintf(outf, "%9.9s %-16.16s\n",dashes, dashes);
+	for (i = 0; i < nsignals_max; i++)
+	{
+		sorted_count[i] = i;
+		if (sigcounts == NULL || sigcounts[i].calls == 0)
+			continue;
+		call_cum += sigcounts[i].calls;
+	}
+	if (sigcounts && sig_sortfun)
+		qsort((void *) sorted_count, nsignals_max, sizeof(int), sig_sortfun);
+	if (sigcounts)
+	{
+		for(i=0; i<nsignals_max; i++)
+		{
+			j = sorted_count[i];
+			if (sigcounts[j].calls == 0)
+				continue;
+			fprintf(outf, "%9d %s\n", sigcounts[j].calls, signame(j));
+		}
+	}
+
+	free(sorted_count);
+	fprintf(outf, "%9.9s %-16.16s\n",dashes, dashes);
+	fprintf(outf, "%9d %s\n", call_cum, "total");
+}
+
 void
 call_summary(FILE *outf)
 {
@@ -243,6 +339,7 @@
 				"System call usage summary for %u bit mode:\n",
 				personality_wordsize[current_personality] * 8);
 		call_summary_pers(outf);
+		call_summary_signal_pers(outf);
 	}

 	if (old_pers != current_personality)
diff -Nur strace-4.5.15/defs.h strace-4.5.15.new/defs.h
--- strace-4.5.15/defs.h	2007-01-16 04:25:52.000000000 +0800
+++ strace-4.5.15.new/defs.h	2007-08-03 08:43:45.000000000 +0800
@@ -439,6 +439,7 @@
 extern long known_scno P((struct tcb *));
 extern int trace_syscall P((struct tcb *));
 extern int count_syscall P((struct tcb *, struct timeval *));
+extern int count_signal P((int));
 extern void printxval P((const struct xlat *, int, const char *));
 extern int printargs P((struct tcb *));
 extern int addflags P((const struct xlat *, int));
@@ -620,3 +621,13 @@
 #endif

 extern int not_failing_only;
+
+/* Anonymous realtime signals. */
+/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
+   constant.  This is what we want.  Otherwise, just use SIGRTMIN. */
+#ifdef SIGRTMIN
+#ifndef __SIGRTMIN
+#define __SIGRTMIN SIGRTMIN
+#define __SIGRTMAX SIGRTMAX /* likewise */
+#endif
+#endif
diff -Nur strace-4.5.15/signal.c strace-4.5.15.new/signal.c
--- strace-4.5.15/signal.c	2007-01-12 06:08:38.000000000 +0800
+++ strace-4.5.15.new/signal.c	2007-08-03 09:11:54.000000000 +0800
@@ -252,16 +252,6 @@

 #endif /* HAVE_SIGACTION */

-/* Anonymous realtime signals. */
-/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
-   constant.  This is what we want.  Otherwise, just use SIGRTMIN. */
-#ifdef SIGRTMIN
-#ifndef __SIGRTMIN
-#define __SIGRTMIN SIGRTMIN
-#define __SIGRTMAX SIGRTMAX /* likewise */
-#endif
-#endif
-
 const char *
 signame(sig)
 int sig;
diff -Nur strace-4.5.15/strace.c strace-4.5.15.new/strace.c
--- strace-4.5.15/strace.c	2006-12-14 05:55:39.000000000 +0800
+++ strace-4.5.15.new/strace.c	2007-08-03 09:30:30.000000000 +0800
@@ -1980,6 +1980,9 @@
 				}
 #endif
 			}
+			if (cflag && (qual_flags[what] & QUAL_SIGNAL)) {
+				count_signal(what);
+			}
 			break;
 		case PR_FAULTED:
 			if (!cflag && (qual_flags[what] & QUAL_FAULT)) {
@@ -2366,6 +2369,10 @@
 					strsignal(WSTOPSIG(status)), pc, addr);
 				printtrailer(tcp);
 			}
+			if (cflag
+				&& (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
+				count_signal(WSTOPSIG(status));
+			}
 			if (((tcp->flags & TCB_ATTACHED) ||
 			     tcp->nclone_threads > 0) &&
 				!sigishandled(tcp, WSTOPSIG(status))) {


-- 
Best Regards,







More information about the Strace-devel mailing list