Two enhancements for kdump.

1) add a "-p pid", which is rather useful for selecting a single pid in
a combined trace file (eg: with ktrace -i).
2) display binary genio data in a more precise format.
This commit is contained in:
Peter Wemm 2003-06-03 01:44:43 +00:00
parent a6f4ec0614
commit ec4beb5d8b
2 changed files with 101 additions and 21 deletions

View File

@ -43,6 +43,7 @@
.Op Fl dnlRT
.Op Fl f Ar file
.Op Fl m Ar maxdata
.Op Fl p Ar pid
.Op Fl t Op cnisuw
.Sh DESCRIPTION
The
@ -83,6 +84,11 @@ values are replaced with the
string.
Suppressing this feature yields a more consistent output format and is
easily amenable to further processing.
.It Fl p Ar pid
Display only trace events that correspond to the process
.Ar pid .
This may be useful when there are multiple processes recorded in the
same trace file.
.It Fl R
Display relative timestamps (time since previous entry).
.It Fl T

View File

@ -72,6 +72,8 @@ void dumpheader(struct ktr_header *);
void ktrsyscall(struct ktr_syscall *);
void ktrsysret(struct ktr_sysret *);
void ktrnamei(char *, int);
void hexdump(char *, int, int);
void visdump(char *, int, int);
void ktrgenio(struct ktr_genio *, int);
void ktrpsig(struct ktr_psig *);
void ktrcsw(struct ktr_csw *);
@ -91,10 +93,11 @@ main(int argc, char *argv[])
void *m;
int trpoints = ALL_POINTS;
int drop_logged;
pid_t pid = 0;
(void) setlocale(LC_CTYPE, "");
while ((ch = getopt(argc,argv,"f:dlm:nRTt:")) != -1)
while ((ch = getopt(argc,argv,"f:dlm:np:RTt:")) != -1)
switch((char)ch) {
case 'f':
tracefile = optarg;
@ -111,6 +114,9 @@ main(int argc, char *argv[])
case 'n':
fancy = 0;
break;
case 'p':
pid = atoi(optarg);
break;
case 'R':
timestamp = 2; /* relative timestamp */
break;
@ -146,7 +152,8 @@ main(int argc, char *argv[])
}
}
if (trpoints & (1<<ktr_header.ktr_type))
dumpheader(&ktr_header);
if (pid == 0 || ktr_header.ktr_pid == pid)
dumpheader(&ktr_header);
if ((ktrlen = ktr_header.ktr_len) < 0)
errx(1, "bogus length 0x%x", ktrlen);
if (ktrlen > size) {
@ -157,6 +164,8 @@ main(int argc, char *argv[])
}
if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
errx(1, "data too short");
if (pid && ktr_header.ktr_pid != pid)
continue;
if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
continue;
drop_logged = 0;
@ -388,30 +397,59 @@ ktrnamei(char *cp, int len)
}
void
ktrgenio(struct ktr_genio *ktr, int len)
hexdump(char *p, int len, int screenwidth)
{
int n, i;
int width;
width = 0;
do {
width += 2;
i = 13; /* base offset */
i += (width / 2) + 1; /* spaces every second byte */
i += (width * 2); /* width of bytes */
i += 3; /* " |" */
i += width; /* each byte */
i += 1; /* "|" */
} while (i < screenwidth);
width -= 2;
for (n = 0; n < len; n += width) {
for (i = n; i < n + width; i++) {
if ((i % width) == 0) { /* beginning of line */
printf(" 0x%04x", i);
}
if ((i % 2) == 0) {
printf(" ");
}
if (i < len)
printf("%02x", p[i] & 0xff);
else
printf(" ");
}
printf(" |");
for (i = n; i < n + width; i++) {
if (i >= len)
break;
if (p[i] >= ' ' && p[i] <= '~')
printf("%c", p[i]);
else
printf(".");
}
printf("|\n");
}
if ((i % width) != 0)
printf("\n");
}
void
visdump(char *dp, int datalen, int screenwidth)
{
int datalen = len - sizeof (struct ktr_genio);
char *dp = (char *)ktr + sizeof (struct ktr_genio);
char *cp;
int col = 0;
char *cp;
int width;
char visbuf[5];
static int screenwidth = 0;
if (screenwidth == 0) {
struct winsize ws;
if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
ws.ws_col > 8)
screenwidth = ws.ws_col;
else
screenwidth = 80;
}
printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
datalen == 1 ? "" : "s");
if (maxdata && datalen > maxdata)
datalen = maxdata;
(void)printf(" \"");
col = 8;
for (;datalen > 0; datalen--, dp++) {
@ -450,6 +488,42 @@ ktrgenio(struct ktr_genio *ktr, int len)
(void)printf("\"\n");
}
void
ktrgenio(struct ktr_genio *ktr, int len)
{
int datalen = len - sizeof (struct ktr_genio);
char *dp = (char *)ktr + sizeof (struct ktr_genio);
static int screenwidth = 0;
int i, binary;
if (screenwidth == 0) {
struct winsize ws;
if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
ws.ws_col > 8)
screenwidth = ws.ws_col;
else
screenwidth = 80;
}
printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
datalen == 1 ? "" : "s");
if (maxdata && datalen > maxdata)
datalen = maxdata;
for (i = 0, binary = 0; i < datalen && binary == 0; i++) {
if (dp[i] >= 32 && dp[i] < 127)
continue;
if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
continue;
binary = 1;
}
if (binary)
hexdump(dp, datalen, screenwidth);
else
visdump(dp, datalen, screenwidth);
}
const char *signames[] = {
"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */
"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */