Module Name:    src
Committed By:   mlelstv
Date:           Sun Aug 21 07:46:52 UTC 2022

Modified Files:
        src/usr.bin/pmap: main.c main.h pmap.1 pmap.c pmap.h

Log Message:
Add -t option to print pmap as underlying RB tree.
Report gap/maxgap fields when dumping vm_map structure.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/usr.bin/pmap/main.c
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/pmap/main.h
cvs rdiff -u -r1.19 -r1.20 src/usr.bin/pmap/pmap.1
cvs rdiff -u -r1.56 -r1.57 src/usr.bin/pmap/pmap.c
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/pmap/pmap.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/pmap/main.c
diff -u src/usr.bin/pmap/main.c:1.29 src/usr.bin/pmap/main.c:1.30
--- src/usr.bin/pmap/main.c:1.29	Wed Nov  4 01:37:55 2020
+++ src/usr.bin/pmap/main.c	Sun Aug 21 07:46:52 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.29 2020/11/04 01:37:55 chs Exp $ */
+/*	$NetBSD: main.c,v 1.30 2022/08/21 07:46:52 mlelstv Exp $ */
 
 /*
  * Copyright (c) 2002, 2003, 2020 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: main.c,v 1.29 2020/11/04 01:37:55 chs Exp $");
+__RCSID("$NetBSD: main.c,v 1.30 2022/08/21 07:46:52 mlelstv Exp $");
 #endif
 
 #include <sys/param.h>
@@ -60,6 +60,7 @@ struct vm_map *st_map, *pt_map, *module_
 u_long kernel_map_addr;
 int debug, verbose, recurse, page_size;
 int print_all, print_map, print_maps, print_solaris, print_ddb;
+int tree;
 rlim_t maxssiz;
 
 struct nlist ksyms[] = {
@@ -133,12 +134,13 @@ main(int argc, char *argv[])
 	pid = -1;
 	which = verbose = debug = 0;
 	print_all = print_map = print_maps = print_solaris = print_ddb = 0;
+	tree = 0;
 	recurse = 0;
 	kmem = kernel = NULL;
 	address = 0;
 	vmspace = &kbit;
 
-	while ((ch = getopt(argc, argv, "A:aD:dE:lM:mN:Pp:RrS:sV:vx")) != -1) {
+	while ((ch = getopt(argc, argv, "A:aD:dE:lM:mN:Pp:RrS:stV:vx")) != -1) {
 		switch (ch) {
 		case 'A':
 		case 'E':
@@ -204,6 +206,9 @@ main(int argc, char *argv[])
 		case 's':
 			print_solaris = 1;
 			break;
+		case 't':
+			tree = 1;
+			break;
 		case 'v':
 			verbose++;
 			break;
@@ -213,7 +218,7 @@ main(int argc, char *argv[])
 			/*NOTREACHED*/
 		case '?':
 		default:
-			fprintf(stderr, "usage: %s [-adlmPRsv] [-A address] "
+			fprintf(stderr, "usage: %s [-adlmPRstv] [-A address] "
 				"[-D number] [-E address] [-M core]\n"
 				"\t[-N system] [-p pid] [-S address] "
 				"[-V address] [pid ...]\n",

Index: src/usr.bin/pmap/main.h
diff -u src/usr.bin/pmap/main.h:1.6 src/usr.bin/pmap/main.h:1.7
--- src/usr.bin/pmap/main.h:1.6	Mon Apr 28 20:24:14 2008
+++ src/usr.bin/pmap/main.h	Sun Aug 21 07:46:52 2022
@@ -1,4 +1,4 @@
-/*      $NetBSD: main.h,v 1.6 2008/04/28 20:24:14 martin Exp $ */
+/*      $NetBSD: main.h,v 1.7 2022/08/21 07:46:52 mlelstv Exp $ */
 
 /*
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -31,6 +31,7 @@
 
 extern int debug, verbose, recurse, page_size;
 extern int print_all, print_map, print_maps, print_solaris, print_ddb;
+extern int tree;
 extern u_long kernel_map_addr;
 extern void *uvm_vnodeops, *uvm_deviceops, *aobj_pager, *ubc_pager;
 extern rlim_t maxssiz;

Index: src/usr.bin/pmap/pmap.1
diff -u src/usr.bin/pmap/pmap.1:1.19 src/usr.bin/pmap/pmap.1:1.20
--- src/usr.bin/pmap/pmap.1:1.19	Mon Jul  3 21:34:20 2017
+++ src/usr.bin/pmap/pmap.1	Sun Aug 21 07:46:52 2022
@@ -1,4 +1,4 @@
-.\"	$NetBSD: pmap.1,v 1.19 2017/07/03 21:34:20 wiz Exp $
+.\"	$NetBSD: pmap.1,v 1.20 2022/08/21 07:46:52 mlelstv Exp $
 .\"
 .\" Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -35,7 +35,7 @@
 .Nd display process memory map
 .Sh SYNOPSIS
 .Nm
-.Op Fl adlmPRsv
+.Op Fl adlmPRstv
 .Op Fl A Ar address
 .Op Fl D Ar number
 .Op Fl E Ar address
@@ -170,6 +170,9 @@ Dumps the vmspace structure found at
 The Solaris style output format, modeled after the Solaris command of
 the same name.
 This is the default output style.
+.It Fl t
+Print entries to the underlying RB tree, root first, followed by lower
+and higher subtree, indented similar to submaps.
 .It Fl V Ar address
 Dumps the vm_map structure found at
 .Ar address .

Index: src/usr.bin/pmap/pmap.c
diff -u src/usr.bin/pmap/pmap.c:1.56 src/usr.bin/pmap/pmap.c:1.57
--- src/usr.bin/pmap/pmap.c:1.56	Wed Nov  4 01:37:55 2020
+++ src/usr.bin/pmap/pmap.c	Sun Aug 21 07:46:52 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.56 2020/11/04 01:37:55 chs Exp $ */
+/*	$NetBSD: pmap.c,v 1.57 2022/08/21 07:46:52 mlelstv Exp $ */
 
 /*
  * Copyright (c) 2002, 2003, 2020 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: pmap.c,v 1.56 2020/11/04 01:37:55 chs Exp $");
+__RCSID("$NetBSD: pmap.c,v 1.57 2022/08/21 07:46:52 mlelstv Exp $");
 #endif
 
 #include <string.h>
@@ -45,9 +45,10 @@ static char *findname(kvm_t *, struct kb
 	struct kbit *, struct kbit *);
 static int search_cache(kvm_t *, struct vnode *, char **, char *, size_t);
 
-/* when recursing, output is indented */
-#define indent(n) ((n) * (recurse > 1 ? recurse - 1 : 0))
+/* when recursing or printing tree, output is indented */
+#define indent(n) ((n) * ((recurse > 1 ? recurse - 1 : 0)) + depth)
 #define rwx (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
+static int depth;
 
 int heapfound;
 
@@ -95,9 +96,7 @@ dump_vm_map(kvm_t *kd, struct kinfo_proc
 	struct kbit *vmspace, struct kbit *vm_map, const char *mname)
 {
 	struct kbit kbit[2], *header, *vm_map_entry;
-	struct vm_map_entry *last, *next;
 	size_t total;
-	u_long addr, end;
 
 	if (S(vm_map) == (size_t)-1) {
 		heapfound = 1;
@@ -214,6 +213,89 @@ dump_vm_map(kvm_t *kd, struct kinfo_proc
 	}
 
 	/* these are the "sub entries" */
+	if (tree)
+		total = dump_vm_map_tree(kd, proc, vmspace,
+			    vm_map, vm_map_entry);
+	else
+		total = dump_vm_map_list(kd, proc, vmspace,
+			    header, vm_map_entry);
+
+	/*
+	 * we're not recursing into a submap, so print totals
+	 */
+	if (recurse < 2) {
+		if (print_solaris)
+			printf("%-*s %8luK\n",
+			       (int)sizeof(void *) * 2 - 2, " total",
+			       (unsigned long)total);
+		if (print_all)
+			printf("%-*s %9luk\n",
+			       (int)sizeof(void *) * 4 - 1, " total",
+			       (unsigned long)total);
+	}
+}
+
+size_t
+dump_vm_map_node(kvm_t *kd, int lvl, struct kinfo_proc2 *proc,
+	struct kbit *vmspace, struct kbit *vm_map_entry,
+	struct vm_map_entry *node)
+{
+	struct vm_map_entry *left, *right;
+	size_t total;
+	u_long addr;
+
+	if (node == NULL)
+		return 0;
+
+	total = 0;
+	addr = (u_long)node;
+	A(vm_map_entry) = addr;
+	S(vm_map_entry) = sizeof(struct vm_map_entry);
+	KDEREF(kd, vm_map_entry);
+
+	left = (struct vm_map_entry *)D(vm_map_entry, vm_map_entry)->rb_node.rb_left;
+	right = (struct vm_map_entry *)D(vm_map_entry, vm_map_entry)->rb_node.rb_right;
+
+	total += dump_vm_map_entry(kd, proc, vmspace, vm_map_entry, 0);
+
+	depth += 2;
+
+	total += dump_vm_map_node(kd, lvl+1, proc, vmspace, vm_map_entry, left);
+	total += dump_vm_map_node(kd, lvl+1, proc, vmspace, vm_map_entry, right);
+
+	depth -= 2;
+
+	return total;
+}
+
+size_t
+dump_vm_map_tree(kvm_t *kd, struct kinfo_proc2 *proc,
+	struct kbit *vmspace, struct kbit *vm_map, struct kbit *vm_map_entry)
+{
+	struct vm_map_entry *root;
+	u_long addr;
+
+	/* these are the "sub entries" */
+	root = (struct vm_map_entry *)D(vm_map, vm_map)->rb_tree.rbt_root;
+
+	addr = (u_long)root;
+	A(vm_map_entry) = addr;
+	S(vm_map_entry) = sizeof(struct vm_map_entry);
+	KDEREF(kd, vm_map_entry);
+
+	depth = 0;
+
+	return dump_vm_map_node(kd, 0, proc, vmspace, vm_map_entry, root);
+}
+
+size_t
+dump_vm_map_list(kvm_t *kd, struct kinfo_proc2 *proc,
+	struct kbit *vmspace, struct kbit *header, struct kbit *vm_map_entry)
+{
+	struct vm_map_entry *last, *next;
+	size_t total;
+	u_long addr, end;
+
 	total = 0;
 	next = D(header, vm_map_entry)->next;
 	last = P(header);
@@ -240,19 +322,7 @@ dump_vm_map(kvm_t *kd, struct kinfo_proc
 		end = D(vm_map_entry, vm_map_entry)->end;
 	}
 
-	/*
-	 * we're not recursing into a submap, so print totals
-	 */
-	if (recurse < 2) {
-		if (print_solaris)
-			printf("%-*s %8luK\n",
-			       (int)sizeof(void *) * 2 - 2, " total",
-			       (unsigned long)total);
-		if (print_all)
-			printf("%-*s %9luk\n",
-			       (int)sizeof(void *) * 4 - 1, " total",
-			       (unsigned long)total);
-	}
+	return total;
 }
 
 size_t
@@ -293,6 +363,8 @@ dump_vm_map_entry(kvm_t *kd, struct kinf
 		printf("%*s    start = %#"PRIxVADDR",", indent(2), "", vme->start);
 		printf(" end = %#"PRIxVADDR",", vme->end);
 		printf(" object.uvm_obj/sub_map = %p,\n", vme->object.uvm_obj);
+		printf("%*s    gap = %#"PRIxVSIZE",", indent(2), "", vme->gap);
+		printf(" maxgap = %#"PRIxVSIZE",\n", vme->maxgap);
 		printf("%*s    offset = %" PRIx64 ",", indent(2), "",
 		       vme->offset);
 		printf(" etype = %#x <%s%s%s%s >,", vme->etype,
@@ -782,6 +854,7 @@ search_cache(kvm_t *kd, struct vnode *vp
 	struct namecache nc;
 	struct vnode_impl vi;
 	u_long vip, ncp, ncp2;
+	size_t nlen;
 
 	vip = (u_long)vp;
 	e = &buf[blen - 1];
@@ -801,10 +874,14 @@ search_cache(kvm_t *kd, struct vnode *vp
 			    (vi.vi_vnode.v_vflag & VV_ROOT) != 0)
 				break;
 			/* Otherwise pull first NCHNAMLEN chars of name. */
+			nlen = MIN((size_t)nc.nc_nlen, NCHNAMLEN);
+			/* too small */
+			if ((size_t)(o - buf) < nlen + (o != e ? 1 : 0))
+				break;
 			if (o != e)
 				*(--o) = '/';
-			o -= MIN((size_t)nc.nc_nlen, NCHNAMLEN);
-			memcpy(o, nc.nc_name, (unsigned)nc.nc_nlen);
+			o -= nlen;
+			memcpy(o, nc.nc_name, nlen);
 			vip = (u_long)nc.nc_dvp;
 			ncp2 = ncp;
 		} else

Index: src/usr.bin/pmap/pmap.h
diff -u src/usr.bin/pmap/pmap.h:1.13 src/usr.bin/pmap/pmap.h:1.14
--- src/usr.bin/pmap/pmap.h:1.13	Wed Nov  4 01:37:55 2020
+++ src/usr.bin/pmap/pmap.h	Sun Aug 21 07:46:52 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.13 2020/11/04 01:37:55 chs Exp $ */
+/*	$NetBSD: pmap.h,v 1.14 2022/08/21 07:46:52 mlelstv Exp $ */
 
 /*
  * Copyright (c) 2002, 2003, 2020 The NetBSD Foundation, Inc.
@@ -146,9 +146,16 @@ struct kbit {
  */
 
 void process_map(kvm_t *, struct kinfo_proc2 *,
-				   struct kbit *, const char *);
+			   struct kbit *, const char *);
 void dump_vm_map(kvm_t *, struct kinfo_proc2 *,
-				   struct kbit *, struct kbit *, const char *);
+			   struct kbit *, struct kbit *, const char *);
+size_t dump_vm_map_list(kvm_t *, struct kinfo_proc2 *,
+			   struct kbit *, struct kbit *, struct kbit *);
+size_t dump_vm_map_tree(kvm_t *, struct kinfo_proc2 *,
+			   struct kbit *, struct kbit *, struct kbit *);
+size_t dump_vm_map_node(kvm_t *, int lvl, struct kinfo_proc2 *,
+			   struct kbit *, struct kbit *, struct vm_map_entry *);
 size_t dump_vm_map_entry(kvm_t *, struct kinfo_proc2 *,
-					   struct kbit *, struct kbit *, int);
+			   struct kbit *, struct kbit *, int);
+
 void dump_amap(kvm_t *, struct kbit *);

Reply via email to