Add a "-H" argument to kdump, which causes kdump to print an additional

field holding the threadid.  This is more useful for libthr than
libpthread, but still quite useful in libpthread as it can be used to
process interlaced records from multiple threads over the course of a
system call.

Detect old ktr_buffer values using the heuristic "if it's negative,
then it must not be a valid threadid".  This may leave something to be
desired.

MFC after:	1 month
Reviewed by:	davidxu
This commit is contained in:
Robert Watson 2005-11-01 14:48:23 +00:00
parent 2bdeb3f9f2
commit a9ac598b36
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151930
2 changed files with 33 additions and 6 deletions

View File

@ -40,7 +40,7 @@
.Nd display kernel trace data
.Sh SYNOPSIS
.Nm
.Op Fl dEnlRT
.Op Fl dEnlHRT
.Op Fl f Ar trfile
.Op Fl m Ar maxdata
.Op Fl p Ar pid
@ -64,6 +64,9 @@ Display elapsed timestamps (time since beginning of trace).
.It Fl f Ar trfile
Display the specified file instead of
.Pa ktrace.out .
.It Fl H
List the thread id (tid) of the thread with each trace record, if available.
If no thread id is available, 0 will be printed.
.It Fl l
Loop reading the trace file, once the end-of-file is reached, waiting for
more data.
@ -123,6 +126,8 @@ The first field is the PID of the process being traced.
The second field is the name of the program being traced.
The third field is the operation that the kernel performed
on behalf of the process.
If thread IDs are being printed, then an additional thread ID column will be
added to the output between the PId field and program name field.
.Pp
In the first line above, the kernel executes the
.Xr writev 2

View File

@ -81,7 +81,7 @@ void ktruser(int, unsigned char *);
void usage(void);
const char *ioctlname(u_long);
int timestamp, decimal, fancy = 1, tail, maxdata;
int timestamp, decimal, fancy = 1, tail, threads, maxdata;
const char *tracefile = DEF_TRACEFILE;
struct ktr_header ktr_header;
@ -98,7 +98,7 @@ main(int argc, char *argv[])
(void) setlocale(LC_CTYPE, "");
while ((ch = getopt(argc,argv,"f:dElm:np:RTt:")) != -1)
while ((ch = getopt(argc,argv,"f:dElm:np:HRTt:")) != -1)
switch((char)ch) {
case 'f':
tracefile = optarg;
@ -121,6 +121,9 @@ main(int argc, char *argv[])
case 'E':
timestamp = 3; /* elapsed timestamp */
break;
case 'H':
threads = 1;
break;
case 'R':
timestamp = 2; /* relative timestamp */
break;
@ -148,7 +151,13 @@ main(int argc, char *argv[])
while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
if (ktr_header.ktr_type & KTR_DROP) {
ktr_header.ktr_type &= ~KTR_DROP;
if (!drop_logged) {
if (!drop_logged && threads) {
(void)printf("%6d %6d %-8.*s Events dropped.\n",
ktr_header.ktr_pid, ktr_header.ktr_tid >
0 ? ktr_header.ktr_tid : 0, MAXCOMLEN,
ktr_header.ktr_comm);
drop_logged = 1;
} else if (!drop_logged) {
(void)printf("%6d %-8.*s Events dropped.\n",
ktr_header.ktr_pid, MAXCOMLEN,
ktr_header.ktr_comm);
@ -251,7 +260,20 @@ dumpheader(struct ktr_header *kth)
type = unknown;
}
(void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, kth->ktr_comm);
/*
* The ktr_tid field was previously the ktr_buffer field, which held
* the kernel pointer value for the buffer associated with data
* following the record header. It now holds a threadid, but only
* for trace files after the change. Older trace files still contain
* kernel pointers. Detect this and suppress the results by printing
* negative tid's as 0.
*/
if (threads)
(void)printf("%6d %6d %-8.*s ", kth->ktr_pid, kth->ktr_tid >
0 ? kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm);
else
(void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN,
kth->ktr_comm);
if (timestamp) {
if (timestamp == 3) {
if (prevtime.tv_sec == 0)
@ -577,6 +599,6 @@ void
usage(void)
{
(void)fprintf(stderr,
"usage: kdump [-dEnlRT] [-f trfile] [-m maxdata] [-p pid] [-t [cnisuw]]\n");
"usage: kdump [-dEnlHRT] [-f trfile] [-m maxdata] [-p pid] [-t [cnisuw]]\n");
exit(1);
}