kdump: resolve sysctl numbers

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

kdump: resolve sysctl numbers

Otto Moerbeek
Hi,

This diff (original version from nicm@) adds resolving of systcl
numbers to names. e.g.:

  914 sysctl   CALL  __sysctl(hw.pagesize,0x8443e4,0x7f7ffffbb8b8,0,0)
  914 sysctl   RET   __sysctl 0
 
utrace(2) wil not make release due to ABI/API lock. But this can make
if I get reviews and ok's,

        -Otto

Index: kdump.c
===================================================================
RCS file: /cvs/src/usr.bin/kdump/kdump.c,v
retrieving revision 1.61
diff -u -p -r1.61 kdump.c
--- kdump.c 19 Jul 2011 18:20:11 -0000 1.61
+++ kdump.c 27 Jul 2011 13:06:16 -0000
@@ -34,17 +34,25 @@
 #include <sys/uio.h>
 #include <sys/ktrace.h>
 #include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/namei.h>
 #include <sys/ptrace.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <sys/vmmeter.h>
 #include <sys/stat.h>
+#include <sys/tty.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #define _KERNEL
 #include <sys/errno.h>
 #undef _KERNEL
+#include <ddb/db_var.h>
+#include <machine/cpu.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -140,6 +148,7 @@ static void ktrgenio(struct ktr_genio *,
 static void ktrnamei(const char *, size_t);
 static void ktrpsig(struct ktr_psig *);
 static void ktrsyscall(struct ktr_syscall *);
+static const char *kresolvsysctl(int, int *, int);
 static void ktrsysret(struct ktr_sysret *);
 static void ktrstruct(char *, size_t);
 static void setemul(const char *);
@@ -511,18 +520,22 @@ ktrsyscall(struct ktr_syscall *ktr)
  break;
  }
  case SYS___sysctl: {
- int *np, n;
+ const char *s;
+ int *np, n, i, *top;
 
  if (!fancy)
  break;
  n = ap[1];
  if (n > CTL_MAXNAME)
  n = CTL_MAXNAME;
- np = (int *)(ap + 6);
- for (; n--; np++) {
+ np = top = (int *)(ap + 6);
+ for (i = 0; n--; np++, i++) {
  if (sep)
  putchar(sep);
- printf("%d", *np);
+ if (resolv && (s = kresolvsysctl(i, top, *np)) != NULL)
+ printf("%s", s);
+ else
+ printf("%d", *np);
  sep = '.';
  }
 
@@ -823,6 +836,111 @@ nonnative:
  narg--;
  }
  (void)printf(")\n");
+}
+
+static struct ctlname topname[] = CTL_NAMES;
+static struct ctlname kernname[] = CTL_KERN_NAMES;
+static struct ctlname vmname[] = CTL_VM_NAMES;
+static struct ctlname fsname[] = CTL_FS_NAMES;
+static struct ctlname netname[] = CTL_NET_NAMES;
+static struct ctlname hwname[] = CTL_HW_NAMES;
+static struct ctlname username[] = CTL_USER_NAMES;
+static struct ctlname debugname[CTL_DEBUG_MAXID];
+static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES;
+static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES;
+static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
+static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES;
+static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
+static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
+static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
+static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES;
+#ifdef CTL_MACHDEP_NAMES
+static struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
+#endif
+static struct ctlname ddbname[] = CTL_DDB_NAMES;
+
+#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
+
+static const char *
+kresolvsysctl(int depth, int *top, int idx)
+{
+ struct ctlname *names;
+ size_t limit;
+
+ names = NULL;
+
+ switch (depth) {
+ case 0:
+ SETNAME(topname);
+ break;
+ case 1:
+ switch (top[0]) {
+ case CTL_KERN:
+ SETNAME(kernname);
+ break;
+ case CTL_VM:
+ SETNAME(vmname);
+ break;
+ case CTL_FS:
+ SETNAME(fsname);
+ break;
+ case CTL_NET:
+ SETNAME(netname);
+ break;
+ case CTL_DEBUG:
+ SETNAME(debugname);
+ break;
+ case CTL_HW:
+ SETNAME(hwname);
+ break;
+#ifdef CTL_MACHDEP_NAMES
+ case CTL_MACHDEP:
+ SETNAME(machdepname);
+ break;
+#endif
+ case CTL_USER:
+ SETNAME(username);
+ break;
+ case CTL_DDB:
+ SETNAME(ddbname);
+ break;
+ }
+ break;
+ case 2:
+ switch (top[0]) {
+ case CTL_KERN:
+ switch (top[1]) {
+ case KERN_MALLOCSTATS:
+ SETNAME(kernmallocname);
+ break;
+ case KERN_FORKSTAT:
+ SETNAME(forkstatname);
+ break;
+ case KERN_NCHSTATS:
+ SETNAME(nchstatsname);
+ break;
+ case KERN_TTY:
+ SETNAME(ttysname);
+ break;
+ case KERN_SEMINFO:
+ SETNAME(semname);
+ break;
+ case KERN_SHMINFO:
+ SETNAME(shmname);
+ break;
+ case KERN_WATCHDOG:
+ SETNAME(watchdogname);
+ break;
+ case KERN_TIMECOUNTER:
+ SETNAME(tcname);
+ break;
+ }
+ }
+ break;
+ }
+ if (names != NULL && idx > 0 && idx < limit)
+ return (names[idx].ctl_name);
+ return (NULL);
 }
 
 static void

Reply | Threaded
Open this post in threaded view
|

Re: kdump: resolve sysctl numbers

Ted Unangst-6
On Wed, Jul 27, 2011, Otto Moerbeek wrote:

> +#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)

userland is not supposed to use nitems I think?  But it keeps sneaking
in because the kernel headers don't protect it.

Reply | Threaded
Open this post in threaded view
|

Re: kdump: resolve sysctl numbers

Otto Moerbeek
On Wed, Jul 27, 2011 at 10:58:22AM -0400, Ted Unangst wrote:

> On Wed, Jul 27, 2011, Otto Moerbeek wrote:
>
> > +#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
>
> userland is not supposed to use nitems I think?  But it keeps sneaking
> in because the kernel headers don't protect it.

Well, I thought it's ok here since kdump already has it's
fingers into the kernel jar anyway.

        -Otto

Reply | Threaded
Open this post in threaded view
|

Re: kdump: resolve sysctl numbers

Jasper Lievisse Adriaanse-2
In reply to this post by Ted Unangst-6
On Wed, Jul 27, 2011 at 10:58:22AM -0400, Ted Unangst wrote:
> On Wed, Jul 27, 2011, Otto Moerbeek wrote:
>
> > +#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
>
> userland is not supposed to use nitems I think?  But it keeps sneaking
> in because the kernel headers don't protect it.
That's right. It's used in some places like pcidump, npppd and tmux, but it's
locally defined as:

#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif

--
Cheers,
Jasper

"Capable, generous men do not create victims, they nurture them."

Reply | Threaded
Open this post in threaded view
|

Re: kdump: resolve sysctl numbers

Thordur Bjornsson-2
On 2011 Jul 27 (Wed) at 19:22:34 +0200 (+0200), Jasper Lievisse Adriaanse wrote:

> On Wed, Jul 27, 2011 at 10:58:22AM -0400, Ted Unangst wrote:
> > On Wed, Jul 27, 2011, Otto Moerbeek wrote:
> >
> > > +#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
> >
> > userland is not supposed to use nitems I think?  But it keeps sneaking
> > in because the kernel headers don't protect it.
> That's right. It's used in some places like pcidump, npppd and tmux, but it's
> locally defined as:
>
> #ifndef nitems
> #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
> #endif

What is the reason for this not being kosher yet,
and if it's not ment to be, why isn't it protected by _KERNEL ?