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.
This commit is contained in:
parent
c94a774a3b
commit
e3a7ef5a2a
1
count.c
1
count.c
@ -50,7 +50,6 @@ 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;
|
||||
|
||||
|
9
defs.h
9
defs.h
@ -456,10 +456,17 @@ extern const struct xlat open_access_modes[];
|
||||
#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;
|
||||
|
7
strace.1
7
strace.1
@ -43,7 +43,7 @@ strace \- trace system calls and signals
|
||||
.SH SYNOPSIS
|
||||
.B strace
|
||||
[
|
||||
.B \-dffhiqrtttTvxx
|
||||
.B \-CdffhiqrtttTvxx
|
||||
]
|
||||
[
|
||||
.BI \-a column
|
||||
@ -243,6 +243,11 @@ program exit. On Linux, this attempts to show system time (CPU time spent
|
||||
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
|
||||
|
33
strace.c
33
strace.c
@ -83,7 +83,8 @@ extern char *optarg;
|
||||
|
||||
|
||||
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 @@ main(int argc, char *argv[])
|
||||
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 @@ main(int argc, char *argv[])
|
||||
|
||||
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 @@ trace()
|
||||
}
|
||||
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 @@ trace()
|
||||
}
|
||||
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 @@ Process %d attached (waiting for parent)\n",
|
||||
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 @@ Process %d attached (waiting for parent)\n",
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!cflag
|
||||
if (cflag != CFLAG_ONLY_STATS
|
||||
&& (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
|
||||
unsigned long addr = 0;
|
||||
long pc = 0;
|
||||
|
19
syscall.c
19
syscall.c
@ -2369,7 +2369,7 @@ trace_syscall(struct tcb *tcp)
|
||||
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 @@ trace_syscall(struct tcb *tcp)
|
||||
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 @@ trace_syscall(struct tcb *tcp)
|
||||
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 @@ trace_syscall(struct tcb *tcp)
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user