I'd like to add kdump -E option to print timestamps as time elapsed since the beginning of trace. The option name is from FreeBSD. While here, the patch makes it possible to use a combination of -T -E and -R options to print timestamps in several formats. The idea is also from FreeBSD.
Trivial patch to the man page is not included. Any objections or comments? -uwe
--- kdump.c.~1.125.~ 2016-09-13 04:50:59.000000000 +0300 +++ kdump.c 2017-09-07 04:52:44.488100929 +0300 @@ -72,6 +72,11 @@ #include <sys/syscall.h> +#define TIMESTAMP_NONE 0x0 +#define TIMESTAMP_ABSOLUTE 0x1 +#define TIMESTAMP_ELAPSED 0x2 +#define TIMESTAMP_RELATIVE 0x4 + static int timestamp, decimal, plain, tail, maxdata = -1, numeric; static int word_size = 0; static pid_t do_pid = -1; @@ -162,9 +167,14 @@ } return 0; } - - while ((ch = getopt(argc, argv, "e:f:dlm:Nnp:RTt:xX:")) != -1) { + + timestamp = TIMESTAMP_NONE; + + while ((ch = getopt(argc, argv, "Ee:f:dlm:Nnp:RTt:xX:")) != -1) { switch (ch) { + case 'E': + timestamp |= TIMESTAMP_ELAPSED; + break; case 'e': emul_name = strdup(optarg); /* it's safer to copy it */ break; @@ -194,10 +204,10 @@ plain++; break; case 'R': - timestamp = 2; /* relative timestamp */ + timestamp |= TIMESTAMP_RELATIVE; break; case 'T': - timestamp = 1; + timestamp |= TIMESTAMP_ABSOLUTE; break; case 't': trset = 1; @@ -333,7 +343,7 @@ struct timeval tv; struct timespec ts; }; - static union holdtime prevtime; + static union holdtime starttime, prevtime; union holdtime temp; int col; @@ -388,8 +398,78 @@ col += printf("%6d ", kth->ktr_lid); col += printf("%-8.*s ", MAXCOMLEN, kth->ktr_comm); if (timestamp) { - (void)&prevtime; - if (timestamp == 2) { + if (timestamp & TIMESTAMP_ABSOLUTE) { + switch (kth->ktr_version) { + case KTRFAC_VERSION(KTRFACv0): + temp.tv.tv_sec = kth->ktr_otv.tv_sec; + temp.tv.tv_usec = kth->ktr_otv.tv_usec; + break; + case KTRFAC_VERSION(KTRFACv1): + temp.ts.tv_sec = kth->ktr_ots.tv_sec; + temp.ts.tv_nsec = kth->ktr_ots.tv_nsec; + break; + case KTRFAC_VERSION(KTRFACv2): + temp.ts.tv_sec = kth->ktr_ts.tv_sec; + temp.ts.tv_nsec = kth->ktr_ts.tv_nsec; + break; + default: + goto badversion; + } + + if (kth->ktr_version == KTRFACv0) + col += printf("%lld.%06ld ", + (long long)temp.tv.tv_sec, + (long)temp.tv.tv_usec); + else + col += printf("%lld.%09ld ", + (long long)temp.ts.tv_sec, + (long)temp.ts.tv_nsec); + } + + if (timestamp & TIMESTAMP_ELAPSED) { + switch (kth->ktr_version) { + case KTRFAC_VERSION(KTRFACv0): + if (starttime.tv.tv_sec == 0) { + starttime.tv.tv_sec = kth->ktr_otv.tv_sec; + starttime.tv.tv_usec = kth->ktr_otv.tv_usec; + temp.tv.tv_sec = temp.tv.tv_usec = 0; + } else + timersub(&kth->ktr_otv, + &starttime.tv, &temp.tv); + break; + case KTRFAC_VERSION(KTRFACv1): + if (starttime.ts.tv_sec == 0) { + starttime.ts.tv_sec = kth->ktr_ots.tv_sec; + starttime.ts.tv_nsec = kth->ktr_ots.tv_nsec; + temp.ts.tv_sec = temp.ts.tv_nsec = 0; + } else + timespecsub(&kth->ktr_ots, + &starttime.ts, &temp.ts); + break; + case KTRFAC_VERSION(KTRFACv2): + if (starttime.ts.tv_sec == 0) { + starttime.ts.tv_sec = kth->ktr_ts.tv_sec; + starttime.ts.tv_nsec = kth->ktr_ts.tv_nsec; + temp.ts.tv_sec = temp.ts.tv_nsec = 0; + } else + timespecsub(&kth->ktr_ts, + &starttime.ts, &temp.ts); + break; + default: + goto badversion; + } + + if (kth->ktr_version == KTRFACv0) + col += printf("%lld.%06ld ", + (long long)temp.tv.tv_sec, + (long)temp.tv.tv_usec); + else + col += printf("%lld.%09ld ", + (long long)temp.ts.tv_sec, + (long)temp.ts.tv_nsec); + } + + if (timestamp & TIMESTAMP_RELATIVE) { switch (kth->ktr_version) { case KTRFAC_VERSION(KTRFACv0): if (prevtime.tv.tv_sec == 0) @@ -421,35 +501,23 @@ default: goto badversion; } - } else { - switch (kth->ktr_version) { - case KTRFAC_VERSION(KTRFACv0): - temp.tv.tv_sec = kth->ktr_otv.tv_sec; - temp.tv.tv_usec = kth->ktr_otv.tv_usec; - break; - case KTRFAC_VERSION(KTRFACv1): - temp.ts.tv_sec = kth->ktr_ots.tv_sec; - temp.ts.tv_nsec = kth->ktr_ots.tv_nsec; - break; - case KTRFAC_VERSION(KTRFACv2): - temp.ts.tv_sec = kth->ktr_ts.tv_sec; - temp.ts.tv_nsec = kth->ktr_ts.tv_nsec; - break; - default: - badversion: - err(1, "Unsupported ktrace version %x", - kth->ktr_version); - } + + if (kth->ktr_version == KTRFACv0) + col += printf("%lld.%06ld ", + (long long)temp.tv.tv_sec, + (long)temp.tv.tv_usec); + else + col += printf("%lld.%09ld ", + (long long)temp.ts.tv_sec, + (long)temp.ts.tv_nsec); } - if (kth->ktr_version == KTRFACv0) - col += printf("%lld.%06ld ", - (long long)temp.tv.tv_sec, (long)temp.tv.tv_usec); - else - col += printf("%lld.%09ld ", - (long long)temp.ts.tv_sec, (long)temp.ts.tv_nsec); } col += printf("%-4s ", type); return col; + +badversion: + err(1, "Unsupported ktrace version %x", kth->ktr_version); + /* NOTREACHED */ } static void