diff options
author | rwatson <rwatson@FreeBSD.org> | 2007-12-02 23:31:45 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2007-12-02 23:31:45 +0000 |
commit | 88563131a07695a978d1ea8d582fcaef2bbcf495 (patch) | |
tree | 7dbb26f0de9b1cdfcb17b3932fafcf867ce71aa3 /usr.bin/procstat/procstat_vm.c | |
parent | 2cfd49de5b26f76b5592e60721eee0cb4d5981e7 (diff) | |
download | FreeBSD-src-88563131a07695a978d1ea8d582fcaef2bbcf495.zip FreeBSD-src-88563131a07695a978d1ea8d582fcaef2bbcf495.tar.gz |
Add procstat(1), a process inspection utility. This provides both some
of the missing functionality from procfs(4) and new functionality for
monitoring and debugging specific processes. procstat(1) operates in
the following modes:
-b Display binary information for the process.
-c Display command line arguments for the process.
-f Display file descriptor information for the process.
-k Display the stacks of kernel threads in the process.
-s Display security credential information for the process.
-t Display thread information for the process.
-v Display virtual memory mappings for the process.
Further revision and modes are expected.
Testing, ideas, etc: cognet, sam, Skip Ford <skip at menantico dot com>
Wesley Shields <wxs at atarininja dot org>
Diffstat (limited to 'usr.bin/procstat/procstat_vm.c')
-rw-r--r-- | usr.bin/procstat/procstat_vm.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/usr.bin/procstat/procstat_vm.c b/usr.bin/procstat/procstat_vm.c new file mode 100644 index 0000000..5a00587 --- /dev/null +++ b/usr.bin/procstat/procstat_vm.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/user.h> + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#include "procstat.h" + +void +procstat_vm(pid_t pid, struct kinfo_proc *kipp) +{ + struct kinfo_vmentry *freep, *kve; + int error, i, name[4], ptrwidth; + const char *str; + size_t len; + + ptrwidth = 2*sizeof(void *) + 2; + if (!hflag) + printf("%5s %*s %*s %3s %4s %4s %3s %3s %2s %-2s %-s\n", + "PID", ptrwidth, "START", ptrwidth, "END", "PRT", "RES", + "PRES", "REF", "SHD", "FL", "TP", "PATH"); + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_VMMAP; + name[3] = pid; + + len = 0; + error = sysctl(name, 4, NULL, &len, NULL, 0); + if (error < 0 && errno != ESRCH && errno != EPERM) { + warn("sysctl: kern.proc.vmmap: %d", pid); + return; + } + if (error < 0) + return; + + /* + * Especially if running procstat -sv, we may need room for more + * mappings when printing than were present when we queried, so pad + * out the allocation a bit. + */ + len += sizeof(*kve) * 3; + freep = kve = malloc(len); + if (kve == NULL) + err(-1, "malloc"); + if (sysctl(name, 4, kve, &len, NULL, 0) < 0) { + warn("sysctl: kern.proc.vmmap: %d", pid); + free(freep); + return; + } + + for (i = 0; i < (len / sizeof(*kve)); i++, kve++) { + if (kve->kve_structsize != sizeof(*kve)) + errx(-1, "kinfo_vmentry structure mismatch"); + printf("%5d ", pid); + printf("%*p ", ptrwidth, kve->kve_start); + printf("%*p ", ptrwidth, kve->kve_end); + printf("%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-"); + printf("%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-"); + printf("%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-"); + printf("%4d ", kve->kve_resident); + printf("%4d ", kve->kve_private_resident); + printf("%3d ", kve->kve_ref_count); + printf("%3d ", kve->kve_shadow_count); + printf("%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-"); + printf("%-1s ", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" : + "-"); + switch (kve->kve_type) { + case KVME_TYPE_NONE: + str = "--"; + break; + case KVME_TYPE_DEFAULT: + str = "df"; + break; + case KVME_TYPE_VNODE: + str = "vn"; + break; + case KVME_TYPE_SWAP: + str = "sw"; + break; + case KVME_TYPE_DEVICE: + str = "dv"; + break; + case KVME_TYPE_PHYS: + str = "ph"; + break; + case KVME_TYPE_DEAD: + str = "dd"; + break; + case KVME_TYPE_UNKNOWN: + default: + str = "??"; + break; + } + printf("%-2s ", str); + printf("%-s\n", kve->kve_path); + } + free(freep); +} |