Implement -C option to combine regular and -c output
* defs.h (cflag_t): New enum.
* strace.1: Document -C option.
* strace.c (cflag): Update type.
(main): Handle -C option.
(trace): Update use of cflag.
* count.c (count_syscall): Move clearing of TCB_INSYSCALL to ...
* syscall.c (trace_syscall): ... here. Update use of cflag.
Based on patch by Adrien Kunysz.
diff --git a/count.c b/count.c
index 4e272a3..d0ea016 100644
--- a/count.c
+++ b/count.c
@@ -50,7 +50,6 @@
int
count_syscall(struct tcb *tcp, struct timeval *tv)
{
- tcp->flags &= ~TCB_INSYSCALL;
if (tcp->scno < 0 || tcp->scno >= nsyscalls)
return 0;
diff --git a/defs.h b/defs.h
index 4797e96..62b3719 100644
--- a/defs.h
+++ b/defs.h
@@ -456,10 +456,17 @@
#define TRACE_SIGNAL 020 /* Trace signal-related syscalls. */
#define TRACE_DESC 040 /* Trace file descriptor-related syscalls. */
+typedef enum {
+ CFLAG_NONE = 0,
+ CFLAG_ONLY_STATS,
+ CFLAG_BOTH
+} cflag_t;
+
extern struct tcb **tcbtab;
extern int *qual_flags;
extern int debug, followfork;
-extern int dtime, cflag, xflag, qflag;
+extern int dtime, xflag, qflag;
+extern cflag_t cflag;
extern int acolumn;
extern unsigned int nprocs, tcbtabsize;
extern int max_strlen;
diff --git a/strace.1 b/strace.1
index d35a74e..aff8f41 100644
--- a/strace.1
+++ b/strace.1
@@ -43,7 +43,7 @@
.SH SYNOPSIS
.B strace
[
-.B \-dffhiqrtttTvxx
+.B \-CdffhiqrtttTvxx
]
[
.BI \-a column
@@ -243,6 +243,11 @@
running in the kernel) independent of wall clock time. If -c is used with
-f or -F (below), only aggregate totals for all traced processes are kept.
.TP
+.B \-C
+Like
+.B \-c
+but also print regular output while processes are running.
+.TP
.B \-d
Show some debugging output of
.B strace
diff --git a/strace.c b/strace.c
index 2fb75c9..40f8907 100644
--- a/strace.c
+++ b/strace.c
@@ -83,7 +83,8 @@
int debug = 0, followfork = 0;
-int dtime = 0, cflag = 0, xflag = 0, qflag = 0;
+int dtime = 0, xflag = 0, qflag = 0;
+cflag_t cflag = CFLAG_NONE;
static int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0;
/*
* daemonized_tracer supports -D option.
@@ -719,15 +720,27 @@
qualify("verbose=all");
qualify("signal=all");
while ((c = getopt(argc, argv,
- "+cdfFhiqrtTvVxz"
+ "+cCdfFhiqrtTvVxz"
#ifndef USE_PROCFS
"D"
#endif
"a:e:o:O:p:s:S:u:E:")) != EOF) {
switch (c) {
case 'c':
- cflag++;
- dtime++;
+ if (cflag == CFLAG_BOTH) {
+ fprintf(stderr, "%s: -c and -C are mutually exclusive options\n",
+ progname);
+ exit(1);
+ }
+ cflag = CFLAG_ONLY_STATS;
+ break;
+ case 'C':
+ if (cflag == CFLAG_ONLY_STATS) {
+ fprintf(stderr, "%s: -c and -C are mutually exclusive options\n",
+ progname);
+ exit(1);
+ }
+ cflag = CFLAG_BOTH;
break;
case 'd':
debug++;
@@ -838,7 +851,7 @@
if (followfork > 1 && cflag) {
fprintf(stderr,
- "%s: -c and -ff are mutually exclusive options\n",
+ "%s: (-c or -C) and -ff are mutually exclusive options\n",
progname);
exit(1);
}
@@ -2144,7 +2157,8 @@
}
break;
case PR_SIGNALLED:
- if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) {
+ if (cflag != CFLAG_ONLY_STATS
+ && (qual_flags[what] & QUAL_SIGNAL)) {
printleader(tcp);
tprintf("--- %s (%s) ---",
signame(what), strsignal(what));
@@ -2160,7 +2174,8 @@
}
break;
case PR_FAULTED:
- if (!cflag && (qual_flags[what] & QUAL_FAULT)) {
+ if (cflag != CFLAGS_ONLY_STATS
+ && (qual_flags[what] & QUAL_FAULT)) {
printleader(tcp);
tprintf("=== FAULT %d ===", what);
printtrailer();
@@ -2383,7 +2398,7 @@
if (WIFSIGNALED(status)) {
if (pid == strace_child)
exit_code = 0x100 | WTERMSIG(status);
- if (!cflag
+ if (cflag != CFLAG_ONLY_STATS
&& (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
printleader(tcp);
tprintf("+++ killed by %s %s+++",
@@ -2482,7 +2497,7 @@
}
continue;
}
- if (!cflag
+ if (cflag != CFLAG_ONLY_STATS
&& (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
unsigned long addr = 0;
long pc = 0;
diff --git a/syscall.c b/syscall.c
index a56d7df..6a6fad8 100644
--- a/syscall.c
+++ b/syscall.c
@@ -2369,7 +2369,7 @@
long u_error;
/* Measure the exit time as early as possible to avoid errors. */
- if (dtime)
+ if (dtime || cflag)
gettimeofday(&tv, NULL);
/* BTW, why we don't just memorize syscall no. on entry
@@ -2407,8 +2407,15 @@
tprintf(" resumed> ");
}
- if (cflag)
- return count_syscall(tcp, &tv);
+ if (cflag) {
+ struct timeval t = tv;
+ int rc = count_syscall(tcp, &t);
+ if (cflag == CFLAG_ONLY_STATS)
+ {
+ tcp->flags &= ~TCB_INSYSCALL;
+ return rc;
+ }
+ }
if (res != 1) {
tprintf(") ");
@@ -2647,9 +2654,9 @@
return 0;
}
- if (cflag) {
- gettimeofday(&tcp->etime, NULL);
+ if (cflag == CFLAG_ONLY_STATS) {
tcp->flags |= TCB_INSYSCALL;
+ gettimeofday(&tcp->etime, NULL);
return 0;
}
@@ -2669,7 +2676,7 @@
return -1;
tcp->flags |= TCB_INSYSCALL;
/* Measure the entrance time as late as possible to avoid errors. */
- if (dtime)
+ if (dtime || cflag)
gettimeofday(&tcp->etime, NULL);
return sys_res;
}