1 /* Debugging dump procedures for the VM server. */ 2 3 #include "inc.h" 4 #include <sys/mman.h> 5 #include <minix/vm.h> 6 #include <minix/timers.h> 7 #include "kernel/proc.h" 8 9 #define LINES 24 10 11 static void print_region(struct vm_region_info *vri, int *n) 12 { 13 static int vri_count, vri_prev_set; 14 static struct vm_region_info vri_prev; 15 int is_repeat; 16 17 /* part of a contiguous identical run? */ 18 is_repeat = 19 vri && 20 vri_prev_set && 21 vri->vri_prot == vri_prev.vri_prot && 22 vri->vri_flags == vri_prev.vri_flags && 23 vri->vri_length == vri_prev.vri_length && 24 vri->vri_addr == vri_prev.vri_addr + vri_prev.vri_length; 25 if (vri) { 26 vri_prev_set = 1; 27 vri_prev = *vri; 28 } else { 29 vri_prev_set = 0; 30 } 31 if (is_repeat) { 32 vri_count++; 33 return; 34 } 35 36 if (vri_count > 0) { 37 printf(" (contiguously repeated %d more times)\n", vri_count); 38 (*n)++; 39 vri_count = 0; 40 } 41 42 /* NULL indicates the end of a list of mappings, nothing else to do */ 43 if (!vri) return; 44 45 printf(" %08lx-%08lx %c%c%c (%lu kB)\n", vri->vri_addr, 46 vri->vri_addr + vri->vri_length, 47 (vri->vri_prot & PROT_READ) ? 'r' : '-', 48 (vri->vri_prot & PROT_WRITE) ? 'w' : '-', 49 (vri->vri_prot & PROT_EXEC) ? 'x' : '-', 50 vri->vri_length / 1024L); 51 (*n)++; 52 } 53 54 void 55 vm_dmp(void) 56 { 57 static struct proc proc[NR_TASKS + NR_PROCS]; 58 static struct vm_region_info vri[LINES]; 59 struct vm_stats_info vsi; 60 struct vm_usage_info vui; 61 static int prev_i = -1; 62 static vir_bytes prev_base = 0; 63 int r, r2, i, j, first, n = 0; 64 65 if (prev_i == -1) { 66 if ((r = vm_info_stats(&vsi)) != OK) { 67 printf("IS: warning: couldn't talk to VM: %d\n", r); 68 return; 69 } 70 71 printf("Total %lu kB, free %lu kB, largest free %lu kB, cached %lu kB\n", 72 vsi.vsi_total * (vsi.vsi_pagesize / 1024), 73 vsi.vsi_free * (vsi.vsi_pagesize / 1024), 74 vsi.vsi_largest * (vsi.vsi_pagesize / 1024), 75 vsi.vsi_cached * (vsi.vsi_pagesize / 1024)); 76 n++; 77 printf("\n"); 78 n++; 79 80 prev_i++; 81 } 82 83 if ((r = sys_getproctab(proc)) != OK) { 84 printf("IS: warning: couldn't get copy of process table: %d\n", r); 85 return; 86 } 87 88 for (i = prev_i; i < NR_TASKS + NR_PROCS && n < LINES; i++, prev_base = 0) { 89 if (i < NR_TASKS || isemptyp(&proc[i])) continue; 90 91 /* The first batch dump for each process contains a header line. */ 92 first = prev_base == 0; 93 94 r = vm_info_region(proc[i].p_endpoint, vri, LINES - first, &prev_base); 95 96 if (r < 0) { 97 printf("Process %d (%s): error %d\n", 98 proc[i].p_endpoint, proc[i].p_name, r); 99 n++; 100 continue; 101 } 102 103 if (first) { 104 /* The entire batch should fit on the screen. */ 105 if (n + 1 + r > LINES) { 106 prev_base = 0; /* restart on next page */ 107 break; 108 } 109 110 if ((r2 = vm_info_usage(proc[i].p_endpoint, &vui)) != OK) { 111 printf("Process %d (%s): error %d\n", 112 proc[i].p_endpoint, proc[i].p_name, r2); 113 n++; 114 continue; 115 } 116 117 printf("Process %d (%s): total %lu kB, common %lu kB, " 118 "shared %lu kB\n", 119 proc[i].p_endpoint, proc[i].p_name, 120 vui.vui_total / 1024L, vui.vui_common / 1024L, 121 vui.vui_shared / 1024L); 122 n++; 123 } 124 125 while (r > 0) { 126 for (j = 0; j < r; j++) { 127 print_region(&vri[j], &n); 128 } 129 130 if (LINES - n - 1 <= 0) break; 131 r = vm_info_region(proc[i].p_endpoint, vri, LINES - n - 1, 132 &prev_base); 133 134 if (r < 0) { 135 printf("Process %d (%s): error %d\n", 136 proc[i].p_endpoint, proc[i].p_name, r); 137 n++; 138 } 139 } 140 print_region(NULL, &n); 141 142 if (n > LINES) printf("IS: internal error\n"); 143 if (n == LINES) break; 144 145 /* This may have to wipe out the "--more--" from below. */ 146 printf(" \n"); 147 n++; 148 } 149 150 if (i >= NR_TASKS + NR_PROCS) { 151 i = -1; 152 prev_base = 0; 153 } 154 else printf("--more--\r"); 155 prev_i = i; 156 } 157 158