1*433d6423SLionel Sambuc /* ProcFS - pid.c - by Alen Stojanov and David van Moolenbroek */ 2*433d6423SLionel Sambuc 3*433d6423SLionel Sambuc #include "inc.h" 4*433d6423SLionel Sambuc 5*433d6423SLionel Sambuc #include <sys/mman.h> 6*433d6423SLionel Sambuc #include <minix/vm.h> 7*433d6423SLionel Sambuc 8*433d6423SLionel Sambuc #define S_FRAME_SIZE 4096 /* use malloc if larger than this */ 9*433d6423SLionel Sambuc static char s_frame[S_FRAME_SIZE]; /* static storage for process frame */ 10*433d6423SLionel Sambuc static char *frame; /* pointer to process frame buffer */ 11*433d6423SLionel Sambuc 12*433d6423SLionel Sambuc static void pid_psinfo(int slot); 13*433d6423SLionel Sambuc static void pid_cmdline(int slot); 14*433d6423SLionel Sambuc static void pid_environ(int slot); 15*433d6423SLionel Sambuc static void pid_map(int slot); 16*433d6423SLionel Sambuc 17*433d6423SLionel Sambuc /* The files that are dynamically created in each PID directory. The data field 18*433d6423SLionel Sambuc * contains each file's read function. Subdirectories are not yet supported. 19*433d6423SLionel Sambuc */ 20*433d6423SLionel Sambuc struct file pid_files[] = { 21*433d6423SLionel Sambuc { "psinfo", REG_ALL_MODE, (data_t) pid_psinfo }, 22*433d6423SLionel Sambuc { "cmdline", REG_ALL_MODE, (data_t) pid_cmdline }, 23*433d6423SLionel Sambuc { "environ", REG_ALL_MODE, (data_t) pid_environ }, 24*433d6423SLionel Sambuc { "map", REG_ALL_MODE, (data_t) pid_map }, 25*433d6423SLionel Sambuc { NULL, 0, (data_t) NULL } 26*433d6423SLionel Sambuc }; 27*433d6423SLionel Sambuc 28*433d6423SLionel Sambuc /*===========================================================================* 29*433d6423SLionel Sambuc * is_zombie * 30*433d6423SLionel Sambuc *===========================================================================*/ 31*433d6423SLionel Sambuc static int is_zombie(int slot) 32*433d6423SLionel Sambuc { 33*433d6423SLionel Sambuc /* Is the given slot a zombie process? 34*433d6423SLionel Sambuc */ 35*433d6423SLionel Sambuc 36*433d6423SLionel Sambuc return (slot >= NR_TASKS && 37*433d6423SLionel Sambuc (mproc[slot - NR_TASKS].mp_flags & (TRACE_ZOMBIE | ZOMBIE))); 38*433d6423SLionel Sambuc } 39*433d6423SLionel Sambuc 40*433d6423SLionel Sambuc /*===========================================================================* 41*433d6423SLionel Sambuc * pid_psinfo * 42*433d6423SLionel Sambuc *===========================================================================*/ 43*433d6423SLionel Sambuc static void pid_psinfo(int i) 44*433d6423SLionel Sambuc { 45*433d6423SLionel Sambuc /* Print information used by ps(1) and top(1). 46*433d6423SLionel Sambuc */ 47*433d6423SLionel Sambuc int pi, task, state, type, p_state, f_state; 48*433d6423SLionel Sambuc char name[PROC_NAME_LEN+1], *p; 49*433d6423SLionel Sambuc struct vm_usage_info vui; 50*433d6423SLionel Sambuc pid_t ppid; 51*433d6423SLionel Sambuc 52*433d6423SLionel Sambuc pi = i - NR_TASKS; 53*433d6423SLionel Sambuc task = proc[i].p_nr < 0; 54*433d6423SLionel Sambuc 55*433d6423SLionel Sambuc /* Get the name of the process. Spaces would mess up the format.. */ 56*433d6423SLionel Sambuc if (task || mproc[i].mp_name[0] == 0) 57*433d6423SLionel Sambuc strncpy(name, proc[i].p_name, sizeof(name) - 1); 58*433d6423SLionel Sambuc else 59*433d6423SLionel Sambuc strncpy(name, mproc[pi].mp_name, sizeof(name) - 1); 60*433d6423SLionel Sambuc name[sizeof(name) - 1] = 0; 61*433d6423SLionel Sambuc if ((p = strchr(name, ' ')) != NULL) 62*433d6423SLionel Sambuc p[0] = 0; 63*433d6423SLionel Sambuc 64*433d6423SLionel Sambuc /* Get the type of the process. */ 65*433d6423SLionel Sambuc if (task) 66*433d6423SLionel Sambuc type = TYPE_TASK; 67*433d6423SLionel Sambuc else if (mproc[i].mp_flags & PRIV_PROC) 68*433d6423SLionel Sambuc type = TYPE_SYSTEM; 69*433d6423SLionel Sambuc else 70*433d6423SLionel Sambuc type = TYPE_USER; 71*433d6423SLionel Sambuc 72*433d6423SLionel Sambuc /* Get the state of the process. */ 73*433d6423SLionel Sambuc if (!task) { 74*433d6423SLionel Sambuc if (is_zombie(i)) 75*433d6423SLionel Sambuc state = STATE_ZOMBIE; /* zombie */ 76*433d6423SLionel Sambuc else if (mproc[pi].mp_flags & TRACE_STOPPED) 77*433d6423SLionel Sambuc state = STATE_STOP; /* stopped (traced) */ 78*433d6423SLionel Sambuc else if (proc[i].p_rts_flags == 0) 79*433d6423SLionel Sambuc state = STATE_RUN; /* in run-queue */ 80*433d6423SLionel Sambuc else if (fp_is_blocked(&fproc[pi]) || 81*433d6423SLionel Sambuc (mproc[pi].mp_flags & (WAITING | SIGSUSPENDED))) 82*433d6423SLionel Sambuc state = STATE_SLEEP; /* sleeping */ 83*433d6423SLionel Sambuc else 84*433d6423SLionel Sambuc state = STATE_WAIT; /* waiting */ 85*433d6423SLionel Sambuc } else { 86*433d6423SLionel Sambuc if (proc[i].p_rts_flags == 0) 87*433d6423SLionel Sambuc state = STATE_RUN; /* in run-queue */ 88*433d6423SLionel Sambuc else 89*433d6423SLionel Sambuc state = STATE_WAIT; /* other i.e. waiting */ 90*433d6423SLionel Sambuc } 91*433d6423SLionel Sambuc 92*433d6423SLionel Sambuc /* We assume that even if a process has become a zombie, its kernel 93*433d6423SLionel Sambuc * proc entry still contains the old (but valid) information. Currently 94*433d6423SLionel Sambuc * this is true, but in the future we may have to filter some fields. 95*433d6423SLionel Sambuc */ 96*433d6423SLionel Sambuc buf_printf("%d %c %d %s %c %d %d %lu %lu %lu %lu", 97*433d6423SLionel Sambuc PSINFO_VERSION, /* information version */ 98*433d6423SLionel Sambuc type, /* process type */ 99*433d6423SLionel Sambuc (int) proc[i].p_endpoint, /* process endpoint */ 100*433d6423SLionel Sambuc name, /* process name */ 101*433d6423SLionel Sambuc state, /* process state letter */ 102*433d6423SLionel Sambuc (int) P_BLOCKEDON(&proc[i]), /* endpt blocked on, or NONE */ 103*433d6423SLionel Sambuc (int) proc[i].p_priority, /* process priority */ 104*433d6423SLionel Sambuc (long) proc[i].p_user_time, /* user time */ 105*433d6423SLionel Sambuc (long) proc[i].p_sys_time, /* system time */ 106*433d6423SLionel Sambuc ex64hi(proc[i].p_cycles), /* execution cycles */ 107*433d6423SLionel Sambuc ex64lo(proc[i].p_cycles) 108*433d6423SLionel Sambuc ); 109*433d6423SLionel Sambuc 110*433d6423SLionel Sambuc memset(&vui, 0, sizeof(vui)); 111*433d6423SLionel Sambuc 112*433d6423SLionel Sambuc if (!is_zombie(i)) { 113*433d6423SLionel Sambuc /* We don't care if this fails. */ 114*433d6423SLionel Sambuc (void) vm_info_usage(proc[i].p_endpoint, &vui); 115*433d6423SLionel Sambuc } 116*433d6423SLionel Sambuc 117*433d6423SLionel Sambuc /* If the process is not a kernel task, we add some extra info. */ 118*433d6423SLionel Sambuc if (!task) { 119*433d6423SLionel Sambuc if (mproc[pi].mp_flags & WAITING) 120*433d6423SLionel Sambuc p_state = PSTATE_WAITING; 121*433d6423SLionel Sambuc else if (mproc[pi].mp_flags & SIGSUSPENDED) 122*433d6423SLionel Sambuc p_state = PSTATE_SIGSUSP; 123*433d6423SLionel Sambuc else 124*433d6423SLionel Sambuc p_state = '-'; 125*433d6423SLionel Sambuc 126*433d6423SLionel Sambuc if (mproc[pi].mp_parent == pi) 127*433d6423SLionel Sambuc ppid = NO_PID; 128*433d6423SLionel Sambuc else 129*433d6423SLionel Sambuc ppid = mproc[mproc[pi].mp_parent].mp_pid; 130*433d6423SLionel Sambuc 131*433d6423SLionel Sambuc switch (fproc[pi].fp_blocked_on) { 132*433d6423SLionel Sambuc case FP_BLOCKED_ON_NONE: f_state = FSTATE_NONE; break; 133*433d6423SLionel Sambuc case FP_BLOCKED_ON_PIPE: f_state = FSTATE_PIPE; break; 134*433d6423SLionel Sambuc case FP_BLOCKED_ON_LOCK: f_state = FSTATE_LOCK; break; 135*433d6423SLionel Sambuc case FP_BLOCKED_ON_POPEN: f_state = FSTATE_POPEN; break; 136*433d6423SLionel Sambuc case FP_BLOCKED_ON_SELECT: f_state = FSTATE_SELECT; break; 137*433d6423SLionel Sambuc case FP_BLOCKED_ON_OTHER: f_state = FSTATE_TASK; break; 138*433d6423SLionel Sambuc default: f_state = FSTATE_UNKNOWN; 139*433d6423SLionel Sambuc } 140*433d6423SLionel Sambuc 141*433d6423SLionel Sambuc buf_printf(" %lu %lu %lu %c %d %u %u %u %d %c %d %u", 142*433d6423SLionel Sambuc vui.vui_total, /* total memory */ 143*433d6423SLionel Sambuc vui.vui_common, /* common memory */ 144*433d6423SLionel Sambuc vui.vui_shared, /* shared memory */ 145*433d6423SLionel Sambuc p_state, /* sleep state */ 146*433d6423SLionel Sambuc ppid, /* parent PID */ 147*433d6423SLionel Sambuc mproc[pi].mp_realuid, /* real UID */ 148*433d6423SLionel Sambuc mproc[pi].mp_effuid, /* effective UID */ 149*433d6423SLionel Sambuc mproc[pi].mp_procgrp, /* process group */ 150*433d6423SLionel Sambuc mproc[pi].mp_nice, /* nice value */ 151*433d6423SLionel Sambuc f_state, /* VFS block state */ 152*433d6423SLionel Sambuc (int) (fproc[pi].fp_blocked_on == FP_BLOCKED_ON_OTHER) 153*433d6423SLionel Sambuc ? fproc[pi].fp_task : NONE, /* block proc */ 154*433d6423SLionel Sambuc fproc[pi].fp_tty /* controlling tty */ 155*433d6423SLionel Sambuc ); 156*433d6423SLionel Sambuc } 157*433d6423SLionel Sambuc 158*433d6423SLionel Sambuc /* always add kernel cycles */ 159*433d6423SLionel Sambuc buf_printf(" %lu %lu %lu %lu", 160*433d6423SLionel Sambuc ex64hi(proc[i].p_kipc_cycles), 161*433d6423SLionel Sambuc ex64lo(proc[i].p_kipc_cycles), 162*433d6423SLionel Sambuc ex64hi(proc[i].p_kcall_cycles), 163*433d6423SLionel Sambuc ex64lo(proc[i].p_kcall_cycles)); 164*433d6423SLionel Sambuc 165*433d6423SLionel Sambuc /* add total memory for tasks at the end */ 166*433d6423SLionel Sambuc if(task) buf_printf(" %lu", vui.vui_total); 167*433d6423SLionel Sambuc 168*433d6423SLionel Sambuc /* Newline at the end of the file. */ 169*433d6423SLionel Sambuc buf_printf("\n"); 170*433d6423SLionel Sambuc } 171*433d6423SLionel Sambuc 172*433d6423SLionel Sambuc /*===========================================================================* 173*433d6423SLionel Sambuc * put_frame * 174*433d6423SLionel Sambuc *===========================================================================*/ 175*433d6423SLionel Sambuc static void put_frame(void) 176*433d6423SLionel Sambuc { 177*433d6423SLionel Sambuc /* If we allocated memory dynamically during a call to get_frame(), 178*433d6423SLionel Sambuc * free it up here. 179*433d6423SLionel Sambuc */ 180*433d6423SLionel Sambuc 181*433d6423SLionel Sambuc if (frame != s_frame) 182*433d6423SLionel Sambuc free(frame); 183*433d6423SLionel Sambuc } 184*433d6423SLionel Sambuc 185*433d6423SLionel Sambuc /*===========================================================================* 186*433d6423SLionel Sambuc * get_frame * 187*433d6423SLionel Sambuc *===========================================================================*/ 188*433d6423SLionel Sambuc static int get_frame(int slot, vir_bytes *basep, vir_bytes *sizep, 189*433d6423SLionel Sambuc size_t *nargsp) 190*433d6423SLionel Sambuc { 191*433d6423SLionel Sambuc /* Get the execution frame from the top of the given process's stack. 192*433d6423SLionel Sambuc * It may be very large, in which case we temporarily allocate memory 193*433d6423SLionel Sambuc * for it (up to a certain size). 194*433d6423SLionel Sambuc */ 195*433d6423SLionel Sambuc vir_bytes base, size; 196*433d6423SLionel Sambuc size_t nargs; 197*433d6423SLionel Sambuc 198*433d6423SLionel Sambuc if (proc[slot].p_nr < 0 || is_zombie(slot)) 199*433d6423SLionel Sambuc return FALSE; 200*433d6423SLionel Sambuc 201*433d6423SLionel Sambuc /* Get the frame base address and size. Limit the size to whatever we 202*433d6423SLionel Sambuc * can handle. If our static buffer is not sufficiently large to store 203*433d6423SLionel Sambuc * the entire frame, allocate memory dynamically. It is then later 204*433d6423SLionel Sambuc * freed by put_frame(). 205*433d6423SLionel Sambuc */ 206*433d6423SLionel Sambuc base = mproc[slot - NR_TASKS].mp_frame_addr; 207*433d6423SLionel Sambuc size = mproc[slot - NR_TASKS].mp_frame_len; 208*433d6423SLionel Sambuc 209*433d6423SLionel Sambuc if (size < sizeof(size_t)) return FALSE; 210*433d6423SLionel Sambuc 211*433d6423SLionel Sambuc if (size > ARG_MAX) size = ARG_MAX; 212*433d6423SLionel Sambuc 213*433d6423SLionel Sambuc if (size > sizeof(s_frame)) { 214*433d6423SLionel Sambuc frame = malloc(size); 215*433d6423SLionel Sambuc 216*433d6423SLionel Sambuc if (frame == NULL) 217*433d6423SLionel Sambuc return FALSE; 218*433d6423SLionel Sambuc } 219*433d6423SLionel Sambuc else frame = s_frame; 220*433d6423SLionel Sambuc 221*433d6423SLionel Sambuc /* Copy in the complete process frame. */ 222*433d6423SLionel Sambuc if (sys_datacopy(proc[slot].p_endpoint, base, 223*433d6423SLionel Sambuc SELF, (vir_bytes) frame, (phys_bytes) size) != OK) { 224*433d6423SLionel Sambuc put_frame(); 225*433d6423SLionel Sambuc 226*433d6423SLionel Sambuc return FALSE; 227*433d6423SLionel Sambuc } 228*433d6423SLionel Sambuc 229*433d6423SLionel Sambuc frame[size] = 0; /* terminate any last string */ 230*433d6423SLionel Sambuc 231*433d6423SLionel Sambuc nargs = * (size_t *) frame; 232*433d6423SLionel Sambuc if (nargs < 1 || sizeof(size_t) + sizeof(char *) * (nargs + 1) > size) { 233*433d6423SLionel Sambuc put_frame(); 234*433d6423SLionel Sambuc 235*433d6423SLionel Sambuc return FALSE; 236*433d6423SLionel Sambuc } 237*433d6423SLionel Sambuc 238*433d6423SLionel Sambuc *basep = base; 239*433d6423SLionel Sambuc *sizep = size; 240*433d6423SLionel Sambuc *nargsp = nargs; 241*433d6423SLionel Sambuc 242*433d6423SLionel Sambuc /* The caller now has to called put_frame() to clean up. */ 243*433d6423SLionel Sambuc return TRUE; 244*433d6423SLionel Sambuc } 245*433d6423SLionel Sambuc 246*433d6423SLionel Sambuc /*===========================================================================* 247*433d6423SLionel Sambuc * pid_cmdline * 248*433d6423SLionel Sambuc *===========================================================================*/ 249*433d6423SLionel Sambuc static void pid_cmdline(int slot) 250*433d6423SLionel Sambuc { 251*433d6423SLionel Sambuc /* Dump the process's command line as it is contained in the process 252*433d6423SLionel Sambuc * itself. Each argument is terminated with a null character. 253*433d6423SLionel Sambuc */ 254*433d6423SLionel Sambuc vir_bytes base, size, ptr; 255*433d6423SLionel Sambuc size_t i, len, nargs; 256*433d6423SLionel Sambuc char **argv; 257*433d6423SLionel Sambuc 258*433d6423SLionel Sambuc if (!get_frame(slot, &base, &size, &nargs)) 259*433d6423SLionel Sambuc return; 260*433d6423SLionel Sambuc 261*433d6423SLionel Sambuc argv = (char **) &frame[sizeof(size_t)]; 262*433d6423SLionel Sambuc 263*433d6423SLionel Sambuc for (i = 0; i < nargs; i++) { 264*433d6423SLionel Sambuc ptr = (vir_bytes) argv[i] - base; 265*433d6423SLionel Sambuc 266*433d6423SLionel Sambuc /* Check for bad pointers. */ 267*433d6423SLionel Sambuc if ((long) ptr < 0L || ptr >= size) 268*433d6423SLionel Sambuc break; 269*433d6423SLionel Sambuc 270*433d6423SLionel Sambuc len = strlen(&frame[ptr]) + 1; 271*433d6423SLionel Sambuc 272*433d6423SLionel Sambuc buf_append(&frame[ptr], len); 273*433d6423SLionel Sambuc } 274*433d6423SLionel Sambuc 275*433d6423SLionel Sambuc put_frame(); 276*433d6423SLionel Sambuc } 277*433d6423SLionel Sambuc 278*433d6423SLionel Sambuc /*===========================================================================* 279*433d6423SLionel Sambuc * pid_environ * 280*433d6423SLionel Sambuc *===========================================================================*/ 281*433d6423SLionel Sambuc static void pid_environ(int slot) 282*433d6423SLionel Sambuc { 283*433d6423SLionel Sambuc /* Dump the process's initial environment as it is contained in the 284*433d6423SLionel Sambuc * process itself. Each entry is terminated with a null character. 285*433d6423SLionel Sambuc */ 286*433d6423SLionel Sambuc vir_bytes base, size, ptr; 287*433d6423SLionel Sambuc size_t nargs, off, len; 288*433d6423SLionel Sambuc char **envp; 289*433d6423SLionel Sambuc 290*433d6423SLionel Sambuc if (!get_frame(slot, &base, &size, &nargs)) 291*433d6423SLionel Sambuc return; 292*433d6423SLionel Sambuc 293*433d6423SLionel Sambuc off = sizeof(size_t) + sizeof(char *) * (nargs + 1); 294*433d6423SLionel Sambuc envp = (char **) &frame[off]; 295*433d6423SLionel Sambuc 296*433d6423SLionel Sambuc for (;;) { 297*433d6423SLionel Sambuc /* Make sure there is no buffer overrun. */ 298*433d6423SLionel Sambuc if (off + sizeof(char *) > size) 299*433d6423SLionel Sambuc break; 300*433d6423SLionel Sambuc 301*433d6423SLionel Sambuc ptr = (vir_bytes) *envp; 302*433d6423SLionel Sambuc 303*433d6423SLionel Sambuc /* Stop at the terminating NULL pointer. */ 304*433d6423SLionel Sambuc if (ptr == 0L) 305*433d6423SLionel Sambuc break; 306*433d6423SLionel Sambuc 307*433d6423SLionel Sambuc ptr -= base; 308*433d6423SLionel Sambuc 309*433d6423SLionel Sambuc /* Check for bad pointers. */ 310*433d6423SLionel Sambuc if ((long) ptr < 0L || ptr >= size) 311*433d6423SLionel Sambuc break; 312*433d6423SLionel Sambuc 313*433d6423SLionel Sambuc len = strlen(&frame[ptr]) + 1; 314*433d6423SLionel Sambuc 315*433d6423SLionel Sambuc buf_append(&frame[ptr], len); 316*433d6423SLionel Sambuc 317*433d6423SLionel Sambuc off += sizeof(char *); 318*433d6423SLionel Sambuc envp++; 319*433d6423SLionel Sambuc } 320*433d6423SLionel Sambuc 321*433d6423SLionel Sambuc put_frame(); 322*433d6423SLionel Sambuc } 323*433d6423SLionel Sambuc 324*433d6423SLionel Sambuc /*===========================================================================* 325*433d6423SLionel Sambuc * dump_regions * 326*433d6423SLionel Sambuc *===========================================================================*/ 327*433d6423SLionel Sambuc static int dump_regions(int slot) 328*433d6423SLionel Sambuc { 329*433d6423SLionel Sambuc /* Print the virtual memory regions of a process. 330*433d6423SLionel Sambuc */ 331*433d6423SLionel Sambuc struct vm_region_info vri[MAX_VRI_COUNT]; 332*433d6423SLionel Sambuc vir_bytes next; 333*433d6423SLionel Sambuc int i, r, count; 334*433d6423SLionel Sambuc 335*433d6423SLionel Sambuc count = 0; 336*433d6423SLionel Sambuc next = 0; 337*433d6423SLionel Sambuc 338*433d6423SLionel Sambuc do { 339*433d6423SLionel Sambuc r = vm_info_region(proc[slot].p_endpoint, vri, MAX_VRI_COUNT, 340*433d6423SLionel Sambuc &next); 341*433d6423SLionel Sambuc 342*433d6423SLionel Sambuc if (r < 0) 343*433d6423SLionel Sambuc return r; 344*433d6423SLionel Sambuc 345*433d6423SLionel Sambuc if (r == 0) 346*433d6423SLionel Sambuc break; 347*433d6423SLionel Sambuc 348*433d6423SLionel Sambuc for (i = 0; i < r; i++) { 349*433d6423SLionel Sambuc buf_printf("%08lx-%08lx %c%c%c\n", 350*433d6423SLionel Sambuc vri[i].vri_addr, vri[i].vri_addr + vri[i].vri_length, 351*433d6423SLionel Sambuc (vri[i].vri_prot & PROT_READ) ? 'r' : '-', 352*433d6423SLionel Sambuc (vri[i].vri_prot & PROT_WRITE) ? 'w' : '-', 353*433d6423SLionel Sambuc (vri[i].vri_prot & PROT_EXEC) ? 'x' : '-'); 354*433d6423SLionel Sambuc 355*433d6423SLionel Sambuc count++; 356*433d6423SLionel Sambuc } 357*433d6423SLionel Sambuc } while (r == MAX_VRI_COUNT); 358*433d6423SLionel Sambuc 359*433d6423SLionel Sambuc return count; 360*433d6423SLionel Sambuc } 361*433d6423SLionel Sambuc 362*433d6423SLionel Sambuc /*===========================================================================* 363*433d6423SLionel Sambuc * pid_map * 364*433d6423SLionel Sambuc *===========================================================================*/ 365*433d6423SLionel Sambuc static void pid_map(int slot) 366*433d6423SLionel Sambuc { 367*433d6423SLionel Sambuc /* Print a memory map of the process. Obtain the information from VM if 368*433d6423SLionel Sambuc * possible; otherwise fall back on segments from the kernel. 369*433d6423SLionel Sambuc */ 370*433d6423SLionel Sambuc 371*433d6423SLionel Sambuc /* Zombies have no memory. */ 372*433d6423SLionel Sambuc if (is_zombie(slot)) 373*433d6423SLionel Sambuc return; 374*433d6423SLionel Sambuc 375*433d6423SLionel Sambuc /* Kernel tasks also have no memory. */ 376*433d6423SLionel Sambuc if (proc[slot].p_nr >= 0) { 377*433d6423SLionel Sambuc if (dump_regions(slot) != 0) 378*433d6423SLionel Sambuc return; 379*433d6423SLionel Sambuc } 380*433d6423SLionel Sambuc } 381