Example #1
0
int
getdtablecount(void) {
	struct procstat *procstat;
	struct kinfo_proc *kipp;
	struct filestat_list *head;
	struct filestat *fst;
	unsigned int fd_count = 0;
	pid_t pid;
	unsigned int cnt;

	procstat = procstat_open_sysctl();
	if (procstat == NULL)
		return 0;

	pid = getpid();
	
	kipp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt);
	if (kipp == NULL)
		return 0;

	if (cnt != 0) {
		head = procstat_getfiles(procstat, kipp, 0);
		if (head == NULL)
			return 0;
		fst = STAILQ_LAST(head, filestat, next);
		fd_count = fst->fs_fd;
	}
	procstat_freeprocs(procstat, kipp);
	return fd_count;
}
Example #2
0
void
procstat_rusage(struct procstat *procstat, struct kinfo_proc *kipp)
{
	struct kinfo_proc *kip;
	unsigned int count, i;

	if (!hflag) {
		printf("%5s ", "PID");
		if (Hflag)
			printf("%6s ", "TID");
		printf("%-16s %-32s %14s\n", "COMM", "RESOURCE",
		    "VALUE        ");
	}

	if (!Hflag) {
		print_rusage(kipp);
		return;
	}

	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
	    kipp->ki_pid, &count);
	if (kip == NULL)
		return;
	kinfo_proc_sort(kip, count);
	for (i = 0; i < count; i++)
		print_rusage(&kip[i]);
	procstat_freeprocs(procstat, kip);
}
Example #3
0
void
procstat_rusage(struct procstat *procstat, struct kinfo_proc *kipp)
{
	struct kinfo_proc *kip;
	unsigned int count, i;

	if (!hflag) {
		xo_emit("{d:ta/%5s} ", "PID");
		if (Hflag)
			xo_emit("{d:tb/%6s} ", "TID");
		xo_emit("{d:tc/%-16s %-32s %14s}\n", "COMM", "RESOURCE",
		    "VALUE        ");
	}

	if (!Hflag) {
		print_rusage(kipp);
		return;
	}

	xo_emit("{e:process_id/%d}", kipp->ki_pid);
	xo_emit("{e:command/%s}", kipp->ki_comm);
	xo_open_container("threads");

	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
	    kipp->ki_pid, &count);
	if (kip == NULL)
		return;
	kinfo_proc_sort(kip, count);
	for (i = 0; i < count; i++) {
		print_rusage(&kip[i]);
	}

	xo_close_container("threads");
	procstat_freeprocs(procstat, kip);
}
Example #4
0
File: freebsd.c Project: 40a/reptyr
int get_terminal_state(struct steal_pty_state *steal, pid_t target) {
    struct procstat *procstat;
    struct kinfo_proc *kp;
    unsigned int cnt;
    int err = 0;

    procstat = procstat_open_sysctl();
    kp = procstat_getprocs(procstat, KERN_PROC_PID, target, &cnt);
    if (kp == NULL || cnt < 1)
        goto done;

    if (kp->ki_tdev == NODEV) {
        error("Child is not connected to a pseudo-TTY. Unable to steal TTY.");
        err = EINVAL;
        goto done;
    }

    if ((err = find_terminal_emulator(steal)))
        return err;

done:
    procstat_freeprocs(procstat, kp);
    procstat_close(procstat);
    return err;
}
Example #5
0
int
test_procstat(struct tf_test *thiz)
{
	struct procstat *ps;
	struct kinfo_vmentry *kv;
	struct kinfo_proc *kp;
	unsigned cnt, i;

	ps = procstat_open_sysctl();
	thiz->t_assert(ps != NULL);
	cnt = 0;
	kp = procstat_getprocs(ps, KERN_PROC_PID, getpid(), &cnt);
	thiz->t_assert(kp != NULL);
	thiz->t_pf("getprocs retrieved %u procs\n", cnt);
	kv = procstat_getvmmap(ps, kp, &cnt);
	thiz->t_assert(kv != NULL);
	for (i = 0; i < cnt; i++) {
		thiz->t_pf("[%u] type: %d, "
		    "start: 0x%"PRIx64", end: 0x%"PRIx64" "
		    "(sz: %"PRIu64"%c), prot: 0x%x\n",
		    i, kv[i].kve_type, kv[i].kve_start, kv[i].kve_end,
		    SZFORMAT(kv[i].kve_end - kv[i].kve_start),
		    kv[i].kve_protection);
	}
	procstat_freevmmap(ps, kv);
	procstat_freeprocs(ps, kp);
	procstat_close(ps);

	return (TF_SUCC);
}
Example #6
0
File: freebsd.c Project: 40a/reptyr
struct filestat_list* get_procfiles(pid_t pid, struct kinfo_proc **kp, struct procstat **procstat, unsigned int *cnt) {
    int mflg = 0; // include mmapped files
    (*procstat) = procstat_open_sysctl();
    (*kp) = procstat_getprocs(*procstat, KERN_PROC_PID, pid, cnt);
    if ((*kp) == NULL || *cnt < 1)
        return NULL;

    return procstat_getfiles(*procstat, *kp, mflg);
}
Example #7
0
unsigned int getProcesses(QueryContext& context,
                          struct procstat** pstat,
                          struct kinfo_proc** procs) {
  std::set<std::string> pids;

  *pstat = procstat_open_sysctl();
  if (*pstat == nullptr) {
    TLOG << "Problem in procstat_open_sysctl()";
    return 0;
  }

  unsigned int cnt = 0;
  if (context.constraints["pid"].exists(EQUALS)) {
    pids = context.constraints["pid"].getAll(EQUALS);

    // Generate data for all pids in the vector.
    // If there are comparison constraints this could apply the operator
    // before generating the process structure.
    for (const auto& pid : pids) {
      *procs = procstat_getprocs(*pstat, KERN_PROC_PID, std::stoi(pid), &cnt);
      if (*procs == nullptr) {
        TLOG << "Problem retrieving processes";
        procstat_close(*pstat);
        *pstat = nullptr;
        return 0;
      }
    }
  } else {
    // Get all PIDS.
    *procs = procstat_getprocs(*pstat, KERN_PROC_PROC, 0, &cnt);
    if (*procs == nullptr) {
      TLOG << "Problem retrieving processes";
      procstat_close(*pstat);
      *pstat = nullptr;
      return 0;
    }
  }

  return cnt;
}
Example #8
0
File: freebsd.c Project: 40a/reptyr
// Find the PID of the terminal emulator for `target's terminal.
//
// We assume that the terminal emulator is the parent of the session
// leader. This is true in most cases, although in principle you can
// construct situations where it is false. We should fail safe later
// on if this turns out to be wrong, however.
int find_terminal_emulator(struct steal_pty_state *steal) {
    struct procstat *procstat;
    struct kinfo_proc *kp;
    unsigned int cnt;

    procstat = procstat_open_sysctl();
    kp = procstat_getprocs(procstat, KERN_PROC_PID, steal->target_stat.sid, &cnt);

    if (kp && cnt > 0)
        steal->emulator_pid = kp->ki_ppid;

    procstat_freeprocs(procstat, kp);
    procstat_close(procstat);

    return 0;
}
Example #9
0
File: freebsd.c Project: 40a/reptyr
void move_process_group(struct ptrace_child *child, pid_t from, pid_t to) {
    struct procstat *procstat;
    struct kinfo_proc *kp;
    unsigned int cnt;
    int i;
    int err;

    procstat = procstat_open_sysctl();
    kp = procstat_getprocs(procstat, KERN_PROC_PGRP, from, &cnt);

    for (i = 0; i < cnt; i++) {
        debug("Change pgid for pid %d to %d", kp[i].ki_pid, to);
        err = do_syscall(child, setpgid, kp[i].ki_pid, to, 0, 0, 0, 0);
        if (err < 0)
            error(" failed: %s", strerror(-err));
    }
    procstat_freeprocs(procstat, kp);
    procstat_close(procstat);
}
Example #10
0
File: freebsd.c Project: 40a/reptyr
int check_pgroup(pid_t target) {
    struct procstat *procstat;
    struct kinfo_proc *kp;
    pid_t pg;
    unsigned int cnt;

    pg = getpgid(target);

    procstat = procstat_open_sysctl();
    kp = procstat_getprocs(procstat, KERN_PROC_PGRP, pg, &cnt);
    procstat_freeprocs(procstat, kp);
    procstat_close(procstat);

    if (cnt > 1) {
        error("Process %d shares a process group with %d other processes. Unable to attach.\n", target, cnt - 1);
        return EINVAL;
    }

    return 0;
}
Example #11
0
int
gc_vm_tbl_update(_gc_cap struct gc_vm_tbl *vt)
{
#ifdef GC_USE_LIBPROCSTAT
	struct procstat *ps;
	struct kinfo_vmentry *kv;
	struct kinfo_proc *kp;
	unsigned cnt, i;

	ps = procstat_open_sysctl();
	if (ps == NULL)
		return (GC_ERROR);
	cnt = 0;
	kp = procstat_getprocs(ps, KERN_PROC_PID, getpid(), &cnt);
	if (kp == NULL)
		return (GC_ERROR);
	gc_debug("getprocs retrieved %u procs", cnt);
	kv = procstat_getvmmap(ps, kp, &cnt);
	if (kv == NULL)
		return (GC_ERROR);
	gc_debug("getvmmap retrieved %u entries", cnt);
	if (vt->vt_sz < cnt)
		return (GC_TOO_SMALL);
	vt->vt_nent = cnt;
	for (i = 0; i < vt->vt_nent; i++) {
		vt->vt_ent[i].ve_start = kv[i].kve_start;
		vt->vt_ent[i].ve_end = kv[i].kve_end;
		vt->vt_ent[i].ve_prot = kv[i].kve_protection;
		vt->vt_ent[i].ve_type = kv[i].kve_type;
		vt->vt_ent[i].ve_gctype = 0;
		gc_vm_tbl_track(vt, &vt->vt_ent[i]);
	}
	procstat_freevmmap(ps, kv);
	procstat_freeprocs(ps, kp);
	procstat_close(ps);
	return (GC_SUCC);
#else /* !GC_USE_LIBPROCSTAT */
	return (GC_ERROR);
#endif /* GC_USE_LIBPROCSTAT */
}
Example #12
0
File: freebsd.c Project: 40a/reptyr
int check_proc_stopped(pid_t pid, int fd) {
    struct procstat *procstat;
    struct kinfo_proc *kp;
    int state;
    unsigned int cnt;

    procstat = procstat_open_sysctl();
    kp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt);

    if (cnt > 0)
        state = kp->ki_stat;

    procstat_freeprocs(procstat, kp);
    procstat_close(procstat);

    if (cnt < 1)
        return 1;


    if (state == SSTOP)
        return 1;

    return 0;
}
Example #13
0
int
main(int argc, char *argv[])
{
    int ch, interval, tmp;
    int i;
    struct kinfo_proc *p;
    struct procstat *prstat, *cprstat;
    long l;
    pid_t pid;
    char *dummy;
    char *nlistf, *memf;
    int cnt;

    interval = 0;
    memf = nlistf = NULL;
    while ((ch = getopt(argc, argv, "CHLM:N:ORSXabcefijklhrstvw:x")) != -1) {
        switch (ch) {
        case 'C':
            Cflag++;
            break;

        case 'L':
            Lflag++;
            break;

        case 'H':
            Hflag++;
            break;

        case 'M':
            memf = optarg;
            break;

        case 'N':
            nlistf = optarg;
            break;

        case 'O':
            Oflag++;
            break;

        case 'R':
            Rflag++;
            break;

        case 'S':
            Sflag++;
            break;

        case 'X':
            Xflag++;
            break;

        case 'a':
            aflag++;
            break;

        case 'b':
            bflag++;
            break;

        case 'c':
            cflag++;
            break;

        case 'e':
            eflag++;
            break;

        case 'f':
            fflag++;
            break;

        case 'i':
            iflag++;
            break;

        case 'j':
            jflag++;
            break;

        case 'k':
            kflag++;
            break;

        case 'l':
            lflag++;
            break;

        case 'n':
            nflag++;
            break;

        case 'h':
            hflag++;
            break;

        case 'r':
            rflag++;
            break;

        case 's':
            sflag++;
            break;

        case 't':
            tflag++;
            break;

        case 'v':
            vflag++;
            break;

        case 'w':
            l = strtol(optarg, &dummy, 10);
            if (*dummy != '\0')
                usage();
            if (l < 1 || l > INT_MAX)
                usage();
            interval = l;
            break;

        case 'x':
            xflag++;
            break;

        case '?':
        default:
            usage();
        }

    }
    argc -= optind;
    argv += optind;

    /* We require that either 0 or 1 mode flags be set. */
    tmp = Lflag + Oflag + Rflag + Sflag + bflag + cflag + eflag + fflag +
          iflag + jflag + (kflag ? 1 : 0) + lflag + rflag + sflag + tflag +
          vflag + xflag;
    if (!(tmp == 0 || tmp == 1))
        usage();

    /* We allow -k to be specified up to twice, but not more. */
    if (kflag > 2)
        usage();

    /* Must specify either the -a flag or a list of pids. */
    if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
        usage();

    /* Only allow -C with -f. */
    if (Cflag && !fflag)
        usage();

    /* Only allow -X with -S and -R. */
    if (Xflag && !(Sflag || Rflag))
        usage();

    if (memf != NULL)
        prstat = procstat_open_kvm(nlistf, memf);
    else
        prstat = procstat_open_sysctl();
    if (prstat == NULL)
        errx(1, "procstat_open()");
    do {
        if (aflag) {
            p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt);
            if (p == NULL)
                errx(1, "procstat_getprocs()");
            kinfo_proc_sort(p, cnt);
            for (i = 0; i < cnt; i++) {
                procstat(prstat, &p[i]);

                /* Suppress header after first process. */
                hflag = 1;
            }
            procstat_freeprocs(prstat, p);
        }
        for (i = 0; i < argc; i++) {
            l = strtol(argv[i], &dummy, 10);
            if (*dummy == '\0') {
                if (l < 0)
                    usage();
                pid = l;

                p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt);
                if (p == NULL)
                    errx(1, "procstat_getprocs()");
                if (cnt != 0)
                    procstat(prstat, p);
                procstat_freeprocs(prstat, p);
            } else {
                cprstat = procstat_open_core(argv[i]);
                if (cprstat == NULL) {
                    warnx("procstat_open()");
                    continue;
                }
                p = procstat_getprocs(cprstat, KERN_PROC_PID,
                                      -1, &cnt);
                if (p == NULL)
                    errx(1, "procstat_getprocs()");
                if (cnt != 0)
                    procstat(cprstat, p);
                procstat_freeprocs(cprstat, p);
                procstat_close(cprstat);
            }
            /* Suppress header after first process. */
            hflag = 1;
        }
        if (interval)
            sleep(interval);
    } while (interval);
    procstat_close(prstat);
    exit(0);
}
Example #14
0
void
procstat_threads(struct procstat *procstat, struct kinfo_proc *kipp)
{
	struct kinfo_proc *kip;
	unsigned int count, i;
	const char *str;
	char *threadid;

	if (!hflag)
		xo_emit("{T:/%5s %6s %-19s %-19s %2s %4s %-7s %-9s}\n", "PID",
		    "TID", "COMM", "TDNAME", "CPU", "PRI", "STATE", "WCHAN");

	xo_emit("{ek:process_id/%d}", kipp->ki_pid);
	xo_emit("{e:command/%s}", strlen(kipp->ki_comm) ?
		    kipp->ki_comm : "-");
	xo_open_container("threads");

	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
	    kipp->ki_pid, &count);
	if (kip == NULL)
		return;
	kinfo_proc_sort(kip, count);
	for (i = 0; i < count; i++) {
		kipp = &kip[i];
		asprintf(&threadid, "%d", kipp->ki_tid);
		if (threadid == NULL)
			xo_errc(1, ENOMEM, "Failed to allocate memory in "
			    "procstat_threads()");
		xo_open_container(threadid);
		xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid);
		xo_emit("{:thread_id/%6d/%d} ", kipp->ki_tid);
		xo_emit("{d:command/%-19s/%s} ", strlen(kipp->ki_comm) ?
		    kipp->ki_comm : "-");
		xo_emit("{:thread_name/%-19s/%s} ",
		    kinfo_proc_thread_name(kipp));
		if (kipp->ki_oncpu != 255)
			xo_emit("{:cpu/%3d/%d} ", kipp->ki_oncpu);
		else if (kipp->ki_lastcpu != 255)
			xo_emit("{:cpu/%3d/%d} ", kipp->ki_lastcpu);
		else
			xo_emit("{:cpu/%3s/%s} ", "-");
		xo_emit("{:priority/%4d/%d} ", kipp->ki_pri.pri_level);
		switch (kipp->ki_stat) {
		case SRUN:
			str = "run";
			break;

		case SSTOP:
			str = "stop";
			break;

		case SSLEEP:
			str = "sleep";
			break;

		case SLOCK:
			str = "lock";
			break;

		case SWAIT:
			str = "wait";
			break;

		case SZOMB:
			str = "zomb";
			break;

		case SIDL:
			str = "idle";
			break;

		default:
			str = "??";
			break;
		}
		xo_emit("{:run_state/%-7s/%s} ", str);
		if (kipp->ki_kiflag & KI_LOCKBLOCK) {
			xo_emit("{:lock_name/*%-8s/%s} ",
			    strlen(kipp->ki_lockname) ?
			    kipp->ki_lockname : "-");
		} else {
			xo_emit("{:wait_channel/%-9s/%s} ",
			    strlen(kipp->ki_wmesg) ? kipp->ki_wmesg : "-");
		}
		xo_close_container(threadid);
		free(threadid);
		xo_emit("\n");
	}
	xo_close_container("threads");
	procstat_freeprocs(procstat, kip);
}
Example #15
0
void
procstat_threads(struct procstat *procstat, struct kinfo_proc *kipp)
{
	struct kinfo_proc *kip;
	unsigned int count, i;
	const char *str;

	if (!hflag)
		printf("%5s %6s %-16s %-16s %2s %4s %-7s %-9s\n", "PID",
		    "TID", "COMM", "TDNAME", "CPU", "PRI", "STATE", "WCHAN");

	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
	    kipp->ki_pid, &count);
	if (kip == NULL)
		return;
	kinfo_proc_sort(kip, count);
	for (i = 0; i < count; i++) {
		kipp = &kip[i];
		printf("%5d ", kipp->ki_pid);
		printf("%6d ", kipp->ki_tid);
		printf("%-16s ", strlen(kipp->ki_comm) ?
		    kipp->ki_comm : "-");
		printf("%-16s ", (strlen(kipp->ki_tdname) &&
		    (strcmp(kipp->ki_comm, kipp->ki_tdname) != 0)) ?
		    kipp->ki_tdname : "-");
		if (kipp->ki_oncpu != 255)
			printf("%3d ", kipp->ki_oncpu);
		else if (kipp->ki_lastcpu != 255)
			printf("%3d ", kipp->ki_lastcpu);
		else
			printf("%3s ", "-");
		printf("%4d ", kipp->ki_pri.pri_level);
		switch (kipp->ki_stat) {
		case SRUN:
			str = "run";
			break;

		case SSTOP:
			str = "stop";
			break;

		case SSLEEP:
			str = "sleep";
			break;

		case SLOCK:
			str = "lock";
			break;

		case SWAIT:
			str = "wait";
			break;

		case SZOMB:
			str = "zomb";
			break;

		case SIDL:
			str = "idle";
			break;

		default:
			str = "??";
			break;
		}
		printf("%-7s ", str);
		if (kipp->ki_kiflag & KI_LOCKBLOCK) {
			printf("*%-8s ", strlen(kipp->ki_lockname) ?
			    kipp->ki_lockname : "-");
		} else {
			printf("%-9s ", strlen(kipp->ki_wmesg) ?
			    kipp->ki_wmesg : "-");
		}
		printf("\n");
	}
	procstat_freeprocs(procstat, kip);
}
Example #16
0
/**
 * \todo This function contains many cases that do not allow for a
 *       recovery. Currently, xbt_abort() is called but we should
 *       much rather die with the specific reason so that it's easier
 *       to find out what's going on.
 */
XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid)
{
  std::vector<VmMap> ret;
#ifdef __linux__
  /* Open the actual process's proc maps file and create the memory_map_t */
  /* to be returned. */
  char* path = bprintf("/proc/%i/maps", (int) pid);
  FILE *fp = std::fopen(path, "r");
  if (fp == nullptr) {
    std::perror("fopen failed");
    xbt_die("Cannot open %s to investigate the memory map of the process.", path);
  }
  free(path);
  setbuf(fp, nullptr);

  /* Read one line at the time, parse it and add it to the memory map to be returned */
  ssize_t read; /* Number of bytes readed */
  char* line = nullptr;
  std::size_t n = 0; /* Amount of bytes to read by xbt_getline */
  while ((read = xbt_getline(&line, &n, fp)) != -1) {
    /**
     * The lines that we read have this format: (This is just an example)
     * 00602000-00603000 rw-p 00002000 00:28 1837264                            <complete-path-to-file>
     */

    //fprintf(stderr,"%s", line);

    /* Wipeout the new line character */
    line[read - 1] = '\0';

    /* Tokenize the line using spaces as delimiters and store each token in lfields array. We expect 5 tokens for 6 fields */
    char* lfields[6];
    lfields[0] = strtok(line, " ");

    int i;
    for (i = 1; i < 6 && lfields[i - 1] != nullptr; i++) {
      lfields[i] = std::strtok(nullptr, " ");
    }

    /* Check to see if we got the expected amount of columns */
    if (i < 6)
      xbt_die("The memory map apparently only supplied less than 6 columns. Recovery impossible.");

    /* Ok we are good enough to try to get the info we need */
    /* First get the start and the end address of the map   */
    char *tok = std::strtok(lfields[0], "-");
    if (tok == nullptr)
      xbt_die("Start and end address of the map are not concatenated by a hyphen (-). Recovery impossible.");

    VmMap memreg;
    char *endptr;
    memreg.start_addr = std::strtoull(tok, &endptr, 16);
    /* Make sure that the entire string was an hex number */
    if (*endptr != '\0')
      xbt_abort();

    tok = std::strtok(nullptr, "-");
    if (tok == nullptr)
      xbt_abort();

    memreg.end_addr = std::strtoull(tok, &endptr, 16);
    /* Make sure that the entire string was an hex number */
    if (*endptr != '\0')
      xbt_abort();

    /* Get the permissions flags */
    if (std::strlen(lfields[1]) < 4)
      xbt_abort();

    memreg.prot = 0;

    for (i = 0; i < 3; i++){
      switch(lfields[1][i]){
        case 'r':
          memreg.prot |= PROT_READ;
          break;
        case 'w':
          memreg.prot |= PROT_WRITE;
          break;
        case 'x':
          memreg.prot |= PROT_EXEC;
          break;
        default:
          break;
      }
    }
    if (memreg.prot == 0)
      memreg.prot |= PROT_NONE;

    if (lfields[1][3] == 'p') {
      memreg.flags |= MAP_PRIVATE;
    } else {
      memreg.flags |= MAP_SHARED;
      if (lfields[1][3] != 's')
	XBT_WARN("The protection is neither 'p' (private) nor 's' (shared) but '%s'. Let's assume shared, as on b0rken win-ubuntu systems.\nFull line: %s\n",
		 lfields[1], line);
    }

    /* Get the offset value */
    memreg.offset = std::strtoull(lfields[2], &endptr, 16);
    /* Make sure that the entire string was an hex number */
    if (*endptr != '\0')
      xbt_abort();

    /* Get the device major:minor bytes */
    tok = std::strtok(lfields[3], ":");
    if (tok == nullptr)
      xbt_abort();

    memreg.dev_major = (char) strtoul(tok, &endptr, 16);
    /* Make sure that the entire string was an hex number */
    if (*endptr != '\0')
      xbt_abort();

    tok = std::strtok(nullptr, ":");
    if (tok == nullptr)
      xbt_abort();

    memreg.dev_minor = (char) std::strtoul(tok, &endptr, 16);
    /* Make sure that the entire string was an hex number */
    if (*endptr != '\0')
      xbt_abort();

    /* Get the inode number and make sure that the entire string was a long int */
    memreg.inode = strtoul(lfields[4], &endptr, 10);
    if (*endptr != '\0')
      xbt_abort();

    /* And finally get the pathname */
    if (lfields[5])
      memreg.pathname = lfields[5];

    /* Create space for a new map region in the region's array and copy the */
    /* parsed stuff from the temporal memreg variable */
    XBT_DEBUG("Found region for %s", !memreg.pathname.empty() ? memreg.pathname.c_str() : "(null)");

    ret.push_back(std::move(memreg));
  }

  std::free(line);
  std::fclose(fp);
#elif defined __FreeBSD__
  struct procstat *prstat;
  struct kinfo_proc *proc;
  struct kinfo_vmentry *vmentries;
  unsigned int cnt;

  if ((prstat = procstat_open_sysctl()) == NULL) {
    std::perror("procstat_open_sysctl failed");
    xbt_die("Cannot access kernel state information");
  }
  if ((proc = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt)) == NULL) {
    std::perror("procstat_open_sysctl failed");
    xbt_die("Cannot access process information");
  }
  if ((vmentries = procstat_getvmmap(prstat, proc, &cnt)) == NULL) {
    std::perror("procstat_getvmmap failed");
    xbt_die("Cannot access process memory mappings");
  }
  for (unsigned int i = 0; i < cnt; i++) {
    VmMap memreg;

    /* Addresses */
    memreg.start_addr = vmentries[i].kve_start;
    memreg.end_addr = vmentries[i].kve_end;

    /* Permissions */
    memreg.prot = PROT_NONE;
    if (vmentries[i].kve_protection & KVME_PROT_READ)
      memreg.prot |= PROT_READ;
    if (vmentries[i].kve_protection & KVME_PROT_WRITE)
      memreg.prot |= PROT_WRITE;
    if (vmentries[i].kve_protection & KVME_PROT_EXEC)
      memreg.prot |= PROT_EXEC;

    /* Private (copy-on-write) or shared? */
    if (vmentries[i].kve_flags & KVME_FLAG_COW)
      memreg.flags |= MAP_PRIVATE;
    else
      memreg.flags |= MAP_SHARED;

    /* Offset */
    memreg.offset = vmentries[i].kve_offset;

    /* Device : not sure this can be mapped to something outside of Linux? */
    memreg.dev_major = 0;
    memreg.dev_minor = 0;

    /* Inode */
    memreg.inode = vmentries[i].kve_vn_fileid;

     /*
      * Path. Linuxize result by giving an anonymous mapping a path from
      * the previous mapping, provided previous is vnode and has a path,
      * and mark the stack.
      */
    if (vmentries[i].kve_path[0] != '\0')
      memreg.pathname = vmentries[i].kve_path;
    else if (vmentries[i].kve_type == KVME_TYPE_DEFAULT
	    && vmentries[i-1].kve_type == KVME_TYPE_VNODE
        && vmentries[i-1].kve_path[0] != '\0')
      memreg.pathname = vmentries[i-1].kve_path;
    else if (vmentries[i].kve_type == KVME_TYPE_DEFAULT
        && vmentries[i].kve_flags & KVME_FLAG_GROWS_DOWN)
      memreg.pathname = "[stack]";

    /*
     * One last dirty modification: remove write permission from shared
     * libraries private clean pages. This is necessary because simgrid
     * later identifies mappings based on the permissions that are expected
     * when running the Linux kernel.
     */
    if (vmentries[i].kve_type == KVME_TYPE_VNODE
        && ! (vmentries[i].kve_flags & KVME_FLAG_NEEDS_COPY))
      memreg.prot &= ~PROT_WRITE;

    ret.push_back(std::move(memreg));
  }
  procstat_freevmmap(prstat, vmentries);
  procstat_freeprocs(prstat, proc);
  procstat_close(prstat);
#else
  xbt_die("Could not get memory map from process %lli", (long long int) pid);
#endif
  return ret;
}
Example #17
0
int
main(int argc, char *argv[])
{
	int ch, interval, tmp;
	int i;
	struct kinfo_proc *p;
	struct procstat *prstat, *cprstat;
	long l;
	pid_t pid;
	char *dummy;
	char *nlistf, *memf;
	const char *xocontainer;
	int cnt;

	interval = 0;
	memf = nlistf = NULL;
	argc = xo_parse_args(argc, argv);
	xocontainer = "basic";

	while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrsStvw:x")) != -1) {
		switch (ch) {
		case 'C':
			Cflag++;
			break;

		case 'H':
			Hflag++;
			break;

		case 'M':
			memf = optarg;
			break;
		case 'N':
			nlistf = optarg;
			break;
		case 'S':
			Sflag++;
			xocontainer = "cs";
			break;
		case 'a':
			aflag++;
			break;

		case 'b':
			bflag++;
			xocontainer = "binary";
			break;

		case 'c':
			cflag++;
			xocontainer = "arguments";
			break;

		case 'e':
			eflag++;
			xocontainer = "environment";
			break;

		case 'f':
			fflag++;
			xocontainer = "files";
			break;

		case 'i':
			iflag++;
			xocontainer = "signals";
			break;

		case 'j':
			jflag++;
			xocontainer = "thread_signals";
			break;

		case 'k':
			kflag++;
			xocontainer = "kstack";
			break;

		case 'l':
			lflag++;
			xocontainer = "rlimit";
			break;

		case 'n':
			nflag++;
			break;

		case 'h':
			hflag++;
			break;

		case 'r':
			rflag++;
			xocontainer = "rusage";
			break;

		case 's':
			sflag++;
			xocontainer = "credentials";
			break;

		case 't':
			tflag++;
			xocontainer = "threads";
			break;

		case 'v':
			vflag++;
			xocontainer = "vm";
			break;

		case 'w':
			l = strtol(optarg, &dummy, 10);
			if (*dummy != '\0')
				usage();
			if (l < 1 || l > INT_MAX)
				usage();
			interval = l;
			break;

		case 'x':
			xflag++;
			xocontainer = "auxv";
			break;

		case '?':
		default:
			usage();
		}

	}
	argc -= optind;
	argv += optind;

	/* We require that either 0 or 1 mode flags be set. */
	tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 : 0) +
	    lflag + rflag + sflag + tflag + vflag + xflag + Sflag;
	if (!(tmp == 0 || tmp == 1))
		usage();

	/* We allow -k to be specified up to twice, but not more. */
	if (kflag > 2)
		usage();

	/* Must specify either the -a flag or a list of pids. */
	if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
		usage();

	/* Only allow -C with -f. */
	if (Cflag && !fflag)
		usage();

	if (memf != NULL)
		prstat = procstat_open_kvm(nlistf, memf);
	else
		prstat = procstat_open_sysctl();
	if (prstat == NULL)
		xo_errx(1, "procstat_open()");
	do {
		xo_set_version(PROCSTAT_XO_VERSION);
		xo_open_container("procstat");
		xo_open_container(xocontainer);

		if (aflag) {
			p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt);
			if (p == NULL)
				xo_errx(1, "procstat_getprocs()");
			kinfo_proc_sort(p, cnt);
			for (i = 0; i < cnt; i++) {
				procstat(prstat, &p[i]);

				/* Suppress header after first process. */
				hflag = 1;
				xo_flush();
			}
			procstat_freeprocs(prstat, p);
		}
		for (i = 0; i < argc; i++) {
			l = strtol(argv[i], &dummy, 10);
			if (*dummy == '\0') {
				if (l < 0)
					usage();
				pid = l;

				p = procstat_getprocs(prstat, KERN_PROC_PID,
				    pid, &cnt);
				if (p == NULL)
					xo_errx(1, "procstat_getprocs()");
				if (cnt != 0)
					procstat(prstat, p);
				procstat_freeprocs(prstat, p);
			} else {
				cprstat = procstat_open_core(argv[i]);
				if (cprstat == NULL) {
					warnx("procstat_open()");
					continue;
				}
				p = procstat_getprocs(cprstat, KERN_PROC_PID,
				    -1, &cnt);
				if (p == NULL)
					xo_errx(1, "procstat_getprocs()");
				if (cnt != 0)
					procstat(cprstat, p);
				procstat_freeprocs(cprstat, p);
				procstat_close(cprstat);
			}
			/* Suppress header after first process. */
			hflag = 1;
		}

		xo_close_container(xocontainer);
		xo_close_container("procstat");
		xo_finish();
		if (interval)
			sleep(interval);
	} while (interval);

	procstat_close(prstat);

	exit(0);
}
Example #18
0
void
procstat_cs(struct procstat *procstat, struct kinfo_proc *kipp)
{
	cpusetid_t cs;
	cpuset_t mask;
	struct kinfo_proc *kip;
	struct sbuf *cpusetbuf;
	unsigned int count, i;
	int once, twice, lastcpu, cpu;

	if ((procstat_opts & PS_OPT_NOHEADER) == 0)
		xo_emit("{T:/%5s %6s %-19s %-19s %2s %4s %-7s}\n", "PID",
		    "TID", "COMM", "TDNAME", "CPU", "CSID", "CPU MASK");

	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
	    kipp->ki_pid, &count);
	if (kip == NULL)
		return;
	kinfo_proc_sort(kip, count);
	for (i = 0; i < count; i++) {
		kipp = &kip[i];
		xo_emit("{k:process_id/%5d/%d} ", kipp->ki_pid);
		xo_emit("{:thread_id/%6d/%d} ", kipp->ki_tid);
		xo_emit("{:command/%-19s/%s} ", strlen(kipp->ki_comm) ?
		    kipp->ki_comm : "-");
		xo_emit("{:thread_name/%-19s/%s} ",
                    kinfo_proc_thread_name(kipp));
		if (kipp->ki_oncpu != 255)
			xo_emit("{:cpu/%3d/%d} ", kipp->ki_oncpu);
		else if (kipp->ki_lastcpu != 255)
			xo_emit("{:cpu/%3d/%d} ", kipp->ki_lastcpu);
		else
			xo_emit("{:cpu/%3s/%s} ", "-");
		if (cpuset_getid(CPU_LEVEL_CPUSET, CPU_WHICH_TID,
		    kipp->ki_tid, &cs) != 0) {
			cs = CPUSET_INVALID;
		}
		xo_emit("{:cpu_set_id/%4d/%d} ", cs);
		if ((cs != CPUSET_INVALID) && 
		    (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID,
		    kipp->ki_tid, sizeof(mask), &mask) == 0)) {
			lastcpu = -1;
			once = 0;
			twice = 0;
			cpusetbuf = sbuf_new_auto();
			for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
				if (CPU_ISSET(cpu, &mask)) {
					if (once == 0) {
						sbuf_printf(cpusetbuf, "%d",
						    cpu);
						once = 1;
					} else if (cpu == lastcpu + 1) {
						twice = 1;
					} else if (twice == 1) {
						sbuf_printf(cpusetbuf, "-%d,%d",
						    lastcpu, cpu);
						twice = 0;
					} else
						sbuf_printf(cpusetbuf, ",%d",
						    cpu);
					lastcpu = cpu;
				}
			}
			if (once && twice)
				sbuf_printf(cpusetbuf, "-%d", lastcpu);
			if (sbuf_finish(cpusetbuf) != 0)
				xo_err(1, "Could not generate output");
			xo_emit("{:cpu_set/%s}", sbuf_data(cpusetbuf));
			sbuf_delete(cpusetbuf);
		}
		xo_emit("\n");
	}
	procstat_freeprocs(procstat, kip);
}