summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2007-11-28 11:37:42 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2007-11-28 11:37:42 +0000
commita329ce01002c738c1e43e7bcddc20d0874453fdb (patch)
tree9f9aa2be685ba811b95eb5021e7818142b5b1dd8
parent3937b6e342a8cbaf950ed28de103525e35156608 (diff)
add a -d argument, which can be used to peek at values in the kernel.
this is easier than using the ddb console. ok deraadt
-rw-r--r--usr.sbin/pstat/pstat.812
-rw-r--r--usr.sbin/pstat/pstat.c69
2 files changed, 73 insertions, 8 deletions
diff --git a/usr.sbin/pstat/pstat.8 b/usr.sbin/pstat/pstat.8
index b5e18cf1da3..efcbf0d30ea 100644
--- a/usr.sbin/pstat/pstat.8
+++ b/usr.sbin/pstat/pstat.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pstat.8,v 1.34 2007/05/31 19:20:28 jmc Exp $
+.\" $OpenBSD: pstat.8,v 1.35 2007/11/28 11:37:41 tedu Exp $
.\" $NetBSD: pstat.8,v 1.9.4.1 1996/06/02 09:08:17 mrg Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993, 1994
@@ -30,7 +30,7 @@
.\"
.\" from: @(#)pstat.8 8.4 (Berkeley) 4/19/94
.\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: November 28 2007 $
.Dt PSTAT 8
.Os
.Sh NAME
@@ -39,6 +39,7 @@
.Sh SYNOPSIS
.Nm pstat
.Op Fl fknsTtv
+.Op Fl d Ar format
.Op Fl M Ar core
.Op Fl N Ar system
.Sh DESCRIPTION
@@ -56,6 +57,13 @@ is specified.
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl d Ar format
+Print the values of symbols using the specified format.
+Format is a
+.Xr printf 3
+format, without the leading percent.
+Symbol named are read from the remainging command line arguments.
+Addresses may also be specified in hex.
.It Fl f
Print the open file table with these headings:
.Bl -tag -width indent
diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c
index 6cd3f3dc6d1..b790f00d2b6 100644
--- a/usr.sbin/pstat/pstat.c
+++ b/usr.sbin/pstat/pstat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pstat.c,v 1.67 2007/11/26 18:32:33 tedu Exp $ */
+/* $OpenBSD: pstat.c,v 1.68 2007/11/28 11:37:41 tedu Exp $ */
/* $NetBSD: pstat.c,v 1.27 1996/10/23 22:50:06 cgd Exp $ */
/*-
@@ -40,7 +40,7 @@ static char copyright[] =
#if 0
from: static char sccsid[] = "@(#)pstat.c 8.9 (Berkeley) 2/16/94";
#else
-static char *rcsid = "$OpenBSD: pstat.c,v 1.67 2007/11/26 18:32:33 tedu Exp $";
+static char *rcsid = "$OpenBSD: pstat.c,v 1.68 2007/11/28 11:37:41 tedu Exp $";
#endif
#endif /* not lint */
@@ -147,12 +147,19 @@ main(int argc, char *argv[])
int fileflag = 0, swapflag = 0, ttyflag = 0, vnodeflag = 0;
char buf[_POSIX2_LINE_MAX];
int ch;
+ const char *dformat = NULL;
extern char *optarg;
extern int optind;
gid_t gid;
+ int i;
- while ((ch = getopt(argc, argv, "TM:N:fiknstv")) != -1)
+ while ((ch = getopt(argc, argv, "d:TM:N:fiknstv")) != -1)
switch (ch) {
+ case 'd':
+ dformat = optarg;
+ if (*dformat == '%')
+ usage();
+ break;
case 'f':
fileflag = 1;
break;
@@ -187,6 +194,8 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
+ if (dformat && getuid())
+ errx(1, "Only root can use -k");
/*
* Discard setgid privileges if not the running kernel so that bad
* guys can't print interesting stuff from kernel memory.
@@ -196,19 +205,67 @@ main(int argc, char *argv[])
if (setresgid(gid, gid, gid) == -1)
err(1, "setresgid");
- if (vnodeflag)
+ if (vnodeflag || dformat)
if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == 0)
errx(1, "kvm_openfiles: %s", buf);
if (nlistf == NULL && memf == NULL)
if (setresgid(gid, gid, gid) == -1)
err(1, "setresgid");
+ if (dformat) {
+ struct nlist *nl;
+ int longformat = 0, stringformat = 0;
+ char format[5];
+ if (*dformat == 'p' || *dformat == 'l')
+ longformat = sizeof(long) == 8;
+ if (dformat[0] == 'l' && dformat[1] == 'l')
+ longformat = 1;
+ if (*dformat == 's') {
+ stringformat = 1;
+ snprintf(format, sizeof(format), "%%.8s");
+ } else
+ snprintf(format, sizeof(format), "%%%s", dformat);
+
+ nl = calloc(argc + 1, sizeof *nl);
+ if (!nl)
+ err(1, "calloc nl: ");
+ for (i = 0; i < argc; i++) {
+ if (asprintf(&nl[i].n_name, "_%s",
+ argv[i]) == -1)
+ warn("asprintf");
+ }
+ kvm_nlist(kd, nl);
+ globalnl = nl;
+ for (i = 0; i < argc; i++) {
+ printf("%s ", argv[i]);
+ if (!nl[i].n_value && argv[i][0] == '0') {
+ nl[i].n_value = strtoul(argv[i], NULL, 16);
+ nl[i].n_type = N_DATA;
+ }
+ if (!nl[i].n_value)
+ printf("not found\n");
+ else {
+ long long v;
+ printf("at %p: ", nl[i].n_value);
+ if (nl[i].n_type == N_DATA) {
+ KGET1(i, &v, sizeof(v), argv[i]);
+ if (stringformat)
+ printf(format, &v);
+ else if (longformat)
+ printf(format, v);
+ else
+ printf(format, (int)v);
+ }
+ printf("\n");
+ }
+ }
+ }
if (vnodeflag)
if (kvm_nlist(kd, vnodenl) == -1)
errx(1, "kvm_nlist: %s", kvm_geterr(kd));
- if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag))
+ if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag || dformat))
usage();
if (fileflag || totalflag)
filemode();
@@ -1086,6 +1143,6 @@ void
usage(void)
{
(void)fprintf(stderr,
- "usage: pstat [-fknsTtv] [-M core] [-N system]\n");
+ "usage: pstat [-fknsTtv] [-d format] [-M core] [-N system]\n");
exit(1);
}