Пример #1
0
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;
}
Пример #2
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);
}
Пример #3
0
const char *proc_maps(pid_t pid, size_t *start, size_t *end, int *exe_self)
{
    static struct kinfo_vmentry *freep = NULL;
    static unsigned int i, cnt;
    static char *exe_name;

    /* first, init */
    if (freep == NULL) {
        struct kinfo_proc *ki = kinfo_getproc(pid);
        if (ki == NULL) {
            perror("Error in get process info");
            exit(6);
        }
        freep = procstat_getvmmap(procstat_open_sysctl(), ki, &cnt);
        exe_name = ki->ki_comm;
    }

    while (i < cnt) {
        struct kinfo_vmentry *kve = &freep[i++];
        if ((kve->kve_protection & KVME_PROT_EXEC) && kve->kve_path[0] == '/') {
            *start = kve->kve_start;
            *end = kve->kve_end;

            if (exe_self != NULL) {
                *exe_self = (strcmp(exe_name, strrchr(kve->kve_path, '/') + 1) == 0);
            }
            return kve->kve_path;
        }
    }

    i = 0;
    free(freep);
    freep = NULL;
    return NULL;
}
Пример #4
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;
}
Пример #5
0
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);
}
Пример #6
0
// 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;
}
Пример #7
0
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);
}
Пример #8
0
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;
}
Пример #9
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;
}
Пример #10
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 */
}
Пример #11
0
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;
}
Пример #12
0
void
rb_vm_bugreport(const void *ctx)
{
#ifdef __linux__
# define PROC_MAPS_NAME "/proc/self/maps"
#endif
#ifdef PROC_MAPS_NAME
    enum {other_runtime_info = 1};
#else
    enum {other_runtime_info = 0};
#endif
    const rb_vm_t *const vm = GET_VM();

    preface_dump();

    if (vm) {
	SDR();
	rb_backtrace_print_as_bugreport();
	fputs("\n", stderr);
    }

    rb_dump_machine_register(ctx);

#if HAVE_BACKTRACE || defined(_WIN32)
    fprintf(stderr, "-- C level backtrace information "
	    "-------------------------------------------\n");
    rb_print_backtrace();


    fprintf(stderr, "\n");
#endif /* HAVE_BACKTRACE */

    if (other_runtime_info || vm) {
	fprintf(stderr, "-- Other runtime information "
		"-----------------------------------------------\n\n");
    }
    if (vm) {
	int i;
	VALUE name;
	long len;
	const int max_name_length = 1024;
# define LIMITED_NAME_LENGTH(s) \
	(((len = RSTRING_LEN(s)) > max_name_length) ? max_name_length : (int)len)

	name = vm->progname;
	fprintf(stderr, "* Loaded script: %.*s\n",
		LIMITED_NAME_LENGTH(name), RSTRING_PTR(name));
	fprintf(stderr, "\n");
	fprintf(stderr, "* Loaded features:\n\n");
	for (i=0; i<RARRAY_LEN(vm->loaded_features); i++) {
	    name = RARRAY_AREF(vm->loaded_features, i);
	    if (RB_TYPE_P(name, T_STRING)) {
		fprintf(stderr, " %4d %.*s\n", i,
			LIMITED_NAME_LENGTH(name), RSTRING_PTR(name));
	    }
	    else if (RB_TYPE_P(name, T_CLASS) || RB_TYPE_P(name, T_MODULE)) {
		const char *const type = RB_TYPE_P(name, T_CLASS) ?
		    "class" : "module";
		name = rb_search_class_path(rb_class_real(name));
		if (!RB_TYPE_P(name, T_STRING)) {
		    fprintf(stderr, " %4d %s:<unnamed>\n", i, type);
		    continue;
		}
		fprintf(stderr, " %4d %s:%.*s\n", i, type,
			LIMITED_NAME_LENGTH(name), RSTRING_PTR(name));
	    }
	    else {
		VALUE klass = rb_search_class_path(rb_obj_class(name));
		if (!RB_TYPE_P(klass, T_STRING)) {
		    fprintf(stderr, " %4d #<%p:%p>\n", i,
			    (void *)CLASS_OF(name), (void *)name);
		    continue;
		}
		fprintf(stderr, " %4d #<%.*s:%p>\n", i,
			LIMITED_NAME_LENGTH(klass), RSTRING_PTR(klass),
			(void *)name);
	    }
	}
	fprintf(stderr, "\n");
    }

    {
#ifdef PROC_MAPS_NAME
	{
	    FILE *fp = fopen(PROC_MAPS_NAME, "r");
	    if (fp) {
		fprintf(stderr, "* Process memory map:\n\n");

		while (!feof(fp)) {
		    char buff[0x100];
		    size_t rn = fread(buff, 1, 0x100, fp);
		    if (fwrite(buff, 1, rn, stderr) != rn)
			break;
		}

		fclose(fp);
		fprintf(stderr, "\n\n");
	    }
	}
#endif /* __linux__ */
#ifdef HAVE_LIBPROCSTAT
# define MIB_KERN_PROC_PID_LEN 4
	int mib[MIB_KERN_PROC_PID_LEN];
	struct kinfo_proc kp;
	size_t len = sizeof(struct kinfo_proc);
	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC;
	mib[2] = KERN_PROC_PID;
	mib[3] = getpid();
	if (sysctl(mib, MIB_KERN_PROC_PID_LEN, &kp, &len, NULL, 0) == -1) {
	    perror("sysctl");
	}
	else {
	    struct procstat *prstat = procstat_open_sysctl();
	    fprintf(stderr, "* Process memory map:\n\n");
	    procstat_vm(prstat, &kp);
	    procstat_close(prstat);
	    fprintf(stderr, "\n");
	}
#endif /* __FreeBSD__ */
    }
}
Пример #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;
	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);
}
Пример #14
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;
}
Пример #15
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);
}