[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