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

Reply via email to