static uint64_t
get_zone_cap(zoneid_t zid)
{
	rctlblk_t *rblk;
	uint64_t mcap;
	struct ps_prochandle *pr;

	if ((rblk = (rctlblk_t *)malloc(rctlblk_size())) == NULL)
		return (UINT64_MAX);

	if ((pr = grab_zone_proc(zid)) == NULL) {
		free(rblk);
		return (UINT64_MAX);
	}

	if (pr_getrctl(pr, "zone.max-physical-memory", NULL, rblk,
	    RCTL_FIRST)) {
		Pdestroy_agent(pr);
		Prelease(pr, 0);
		free(rblk);
		return (UINT64_MAX);
	}

	Pdestroy_agent(pr);
	Prelease(pr, 0);

	mcap = rctlblk_get_value(rblk);
	free(rblk);
	return (mcap);
}
static struct ps_prochandle *
grab_zone_proc(zoneid_t zid)
{
	DIR *dirp;
	struct dirent *dentp;
	int pid, pid_self, tmp;
	psinfo_t psinfo;
	struct ps_prochandle *pr = NULL;

	pid_self = getpid();

	if ((dirp = opendir("/proc")) == NULL)
		return (NULL);

	while (dentp = readdir(dirp)) {
		pid = atoi(dentp->d_name);

		/* Skip self */
		if (pid == pid_self)
			continue;

		if (proc_get_psinfo(pid, &psinfo) != 0)
			continue;

		if (psinfo.pr_zoneid != zid)
			continue;

		/* attempt to grab process */
		if ((pr = Pgrab(pid, 0, &tmp)) != NULL) {
			if (Psetflags(pr, PR_RLC) != 0) {
				Prelease(pr, 0);
			}
			if (Pcreate_agent(pr) == 0) {
				if (pr_getzoneid(pr) != zid) {
					Prelease(pr, 0);
					continue;
				}

				(void) closedir(dirp);
				return (pr);
			} else {
				Prelease(pr, 0);
			}
		}
	}

	(void) closedir(dirp);
	return (NULL);
}
/*
 * Class:     sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
 * Method:    detach0
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0
  (JNIEnv *env, jobject this_obj) {
  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
  if (ph != NULL) {
     Prelease(ph);
  }
}
Exemple #4
0
/*ARGSUSED*/
void
la_activity(uintptr_t *cookie, uint_t flags)
{
    struct ps_prochandle *P;
    int err, ret;
    GElf_Sym sym;

    if (flags != LA_ACT_CONSISTENT)
        return;

    while (list != NULL) {
        obj_list_t *node = list;
        char *name = node->ol_name;

        list = node->ol_next;

        P = Pgrab(getpid(), PGRAB_RDONLY, &err);
        ret = Plookup_by_name(P, name, "___SUNW_dof", &sym);
        Prelease(P, 0);

        if (ret == 0) {
            dtrace_link_dof((void *)(uintptr_t)sym.st_value,
                            node->ol_lmid, node->ol_name, node->ol_addr);
        }

        free(node->ol_name);
        free(node);
    }
}
Exemple #5
0
/*PRINTFLIKE3*/
static struct ps_prochandle *
dt_proc_error(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *format, ...)
{
	va_list ap;

	va_start(ap, format);
	dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
	va_end(ap);

	if (dpr->dpr_proc != NULL)
		Prelease(dpr->dpr_proc, 0);

	dt_free(dtp, dpr);
	(void) dt_set_errno(dtp, EDT_COMPILER);
	return (NULL);
}
Exemple #6
0
// attach to the process. One and only one exposed stuff
struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len) {
  struct ps_prochandle* ph = NULL;
  thread_info* thr = NULL;

  if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
     snprintf(err_buf, err_buf_len, "can't allocate memory for ps_prochandle");
     print_debug("%s\n", err_buf);
     return NULL;
  }

  if (ptrace_attach(pid, err_buf, err_buf_len) != true) {
     free(ph);
     return NULL;
  }

  // initialize ps_prochandle
  ph->pid = pid;

  // initialize vtable
  ph->ops = &process_ops;

  // read library info and symbol tables, must do this before attaching threads,
  // as the symbols in the pthread library will be used to figure out
  // the list of threads within the same process.
  read_lib_info(ph);

  // read thread info
  read_thread_info(ph, add_new_thread);

  // attach to the threads
  thr = ph->threads;
  while (thr) {
     // don't attach to the main thread again
    if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) {
        // even if one attach fails, we get return NULL
        Prelease(ph);
        return NULL;
     }
     thr = thr->next;
  }
  return ph;
}
Exemple #7
0
static int
ptime_pid(const char *pidstr)
{
	struct ps_prochandle *Pr;
	pid_t pid;
	int gret;

	if ((Pr = proc_arg_grab(pidstr, PR_ARG_PIDS,
	    Fflag | PGRAB_RDONLY, &gret)) == NULL) {
		(void) fprintf(stderr, "%s: cannot examine %s: %s\n",
		    command, pidstr, Pgrab_error(gret));
		return (1);
	}

	pid = Pstatus(Pr)->pr_pid;
	(void) sprintf(procname, "%d", (int)pid);	/* for perr() */
	(void) look(pid);
	Prelease(Pr, 0);
	return (0);
}
Exemple #8
0
/*
 * Class:     sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:    detach0
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_detach0
  (JNIEnv *env, jobject this_obj) {

  jlong ps_prochandle_ptr;
  ps_prochandle_ptr = env->GetLongField(this_obj, ps_prochandle_ptr_ID);
  if(ps_prochandle_ptr != 0L)
    Prelease((struct ps_prochandle*) ps_prochandle_ptr, PRELEASE_CLEAR);

  // release libthread.so
  void* tdb_handle = (void*) env->GetLongField(this_obj, tdb_handle_ID);
  if (tdb_handle != 0)
    dlclose(tdb_handle);

  // Part of workaround for 4705086.

  // get libjvm[_g].so file descriptor and close it.
  int libjvm_fd = env->GetIntField(this_obj, libjvm_fd_ID);
  if (libjvm_fd != -1)
     close(libjvm_fd);
}
Exemple #9
0
static void detach_internal(JNIEnv* env, jobject this_obj) {
  // clear libthread_db stuff
  clear_libthread_db_ptrs(env, this_obj);

  // release ptr to ps_prochandle
  jlong p_ps_prochandle;
  p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
  if (p_ps_prochandle != 0L) {
    Prelease((struct ps_prochandle*) p_ps_prochandle, PRELEASE_CLEAR);
  }

  // part of the class sharing workaround
  int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
  if (classes_jsa_fd != -1) {
    close(classes_jsa_fd);
    struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
    if (pheader != NULL) {
      free(pheader);
    }
  }
}
Exemple #10
0
int
main(int argc, char **argv)
{
	struct ps_prochandle *P;
	int gerr;
	char *prefix = NULL;
	int opt;
	int opt_p = 0, opt_g = 0, opt_c = 0;
	int oflags = 0;
	int i;
	char fname[MAXPATHLEN];
	char path[MAXPATHLEN];
	int err = 0;
	core_content_t content = CC_CONTENT_DEFAULT;
	struct rlimit rlim;

	if ((pname = strrchr(argv[0], '/')) == NULL)
		pname = argv[0];
	else
		argv[0] = ++pname;		/* for getopt() */

	while ((opt = getopt(argc, argv, "o:Fgpc:")) != EOF) {
		switch (opt) {
		case 'o':
			prefix = optarg;
			break;
		case 'c':
			if (proc_str2content(optarg, &content) != 0) {
				(void) fprintf(stderr, "%s: invalid "
				    "content string '%s'\n", pname, optarg);
				goto usage;
			}
			opt_c = 1;
			break;
		case 'F':
			oflags |= PGRAB_FORCE;
			break;
		case 'p':
			opt_p = 1;
			break;
		case 'g':
			opt_g = 1;
			break;
		default:
			goto usage;
		}
	}

	if ((opt_p | opt_g) == 0) {
		if (prefix == NULL)
			prefix = "core";
	} else {
		int options;

		if ((options = core_get_options()) == -1) {
			perror("core_get_options()");
			return (1);
		}

		if (opt_p && !(options & CC_PROCESS_PATH)) {
			(void) fprintf(stderr, "%s: per-process core dumps "
			    "are disabled (ignoring -p)\n", pname);
			opt_p = 0;
		}

		if (opt_g && !(options & CC_GLOBAL_PATH)) {
			(void) fprintf(stderr, "%s: global core dumps "
			    "are disabled (ignoring -g)\n", pname);
			opt_g = 0;
		}

		if ((opt_p | opt_g) == 0 && prefix == NULL)
			return (1);
	}

	argc -= optind;
	argv += optind;

	if (argc == 0)
		goto usage;

	/*
	 * Make sure we'll have enough file descriptors to handle a target
	 * that has many many mappings.
	 */
	if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
		rlim.rlim_cur = rlim.rlim_max;
		(void) setrlimit(RLIMIT_NOFILE, &rlim);
		(void) enable_extended_FILE_stdio(-1, -1);
	}

	for (i = 0; i < argc; i++) {
		P = proc_arg_grab(argv[i], PR_ARG_PIDS, oflags, &gerr);
		if (P == NULL) {
			(void) fprintf(stderr, "%s: cannot grab %s: %s\n",
			    pname, argv[i], Pgrab_error(gerr));
			err++;
			continue;
		}

		if (prefix != NULL) {
			(void) snprintf(path, sizeof (path), "%s.%%p", prefix);
			convert_path(path, fname, sizeof (fname), P);

			gcore(P, fname, content, &err);
		}

		if (opt_p) {
			pid_t pid = Pstatus(P)->pr_pid;
			(void) core_get_process_path(path, sizeof (path), pid);
			convert_path(path, fname, sizeof (fname), P);
			if (!opt_c)
				(void) core_get_process_content(&content, pid);

			gcore(P, fname, content, &err);
		}

		if (opt_g) {
			/*
			 * Global core files are always just readable and
			 * writable by their owner so we temporarily change
			 * the umask.
			 */
			mode_t oldmode = umask(S_IXUSR | S_IRWXG | S_IRWXO);

			(void) core_get_global_path(path, sizeof (path));
			convert_path(path, fname, sizeof (fname), P);
			if (!opt_c)
				(void) core_get_global_content(&content);

			gcore(P, fname, content, &err);

			(void) umask(oldmode);
		}

		Prelease(P, 0);
	}

	return (err != 0);

usage:
	(void) fprintf(stderr, "usage: %s "
	    "[ -pgF ] [ -o filename ] [ -c content ] pid ...\n", pname);
	return (2);
}
Exemple #11
0
/*
 * Force the parent process (ppid) to wait for its child process (pid).
 */
static int
reap(char *arg, pid_t *reap_pid, int *exit_status)
{
	struct ps_prochandle *Pr;
	siginfo_t siginfo;
	psinfo_t psinfo;
	prusage_t usage;
	pid_t pid, ppid;
	time_t elapsed;
	int gret;

	/*
	 * get the specified pid and the psinfo struct
	 */
	if ((pid = proc_arg_psinfo(arg, PR_ARG_PIDS, &psinfo, &gret)) == -1) {
		(void) fprintf(stderr, "%s: cannot examine %s: %s\n",
		    command, arg, Pgrab_error(gret));
		return (1);
	}

	if (psinfo.pr_nlwp != 0) {
		(void) fprintf(stderr, "%s: process not defunct: %d\n",
		    command, (int)pid);
		return (1);
	}

	*exit_status = psinfo.pr_wstat;
	*reap_pid = psinfo.pr_pid;
	ppid = psinfo.pr_ppid;

	if (ppid == 1) {
		(void) fprintf(stderr, "%s: Failed to reap %d: the only "
		    "non-defunct ancestor is 'init'\n", command,
		    (int)pid);
		return (1);
	}

	if (proc_usage(pid, &usage, &gret) == 0) {
		elapsed = usage.pr_tstamp.tv_sec - usage.pr_term.tv_sec;
	} else {
		(void) fprintf(stderr, "%s: cannot examine %d: %s\n",
		    command, (int)pid, Pgrab_error(gret));
		return (1);
	}

	if ((Fflag == 0) && (elapsed < NOREAP_TIME)) {
		(void) fprintf(stderr, "%s: unsafe to reap %d; it has been "
		    "defunct less than %d seconds\n", command, (int)pid,
		    NOREAP_TIME);
		return (1);
	}

	if ((Pr = Pgrab(ppid, Fflag | PGRAB_NOSTOP, &gret)) == NULL) {
		(void) fprintf(stderr, "%s: cannot examine %d: %s\n", command,
		    (int)ppid, Pgrab_error(gret));
		return (1);
	}

	if ((Fflag == 0) && (Pstate(Pr) == PS_STOP)) {
		Prelease(Pr, 0);
		(void) fprintf(stderr, "%s: unsafe to reap %d; parent is "
		    "stopped and may reap status upon restart\n", command,
		    (int)pid);
		return (1);
	}

	/*
	 * Pstop() will fail if the process to be stopped has become a zombie.
	 * This means that we can say with certainty that the child of this
	 * process has not changed parents (i.e. been reparented to init) once
	 * the Pstop() succeeds.
	 */
	if (Pstop(Pr, 1000) != 0) {
		Prelease(Pr, 0);
		(void) fprintf(stderr, "%s: failed to stop %d: %s", command,
		    (int)ppid, strerror(errno));
		return (1);
	}

	if (pr_waitid(Pr, P_PID, pid, &siginfo, WEXITED|WNOHANG) != 0) {
		Prelease(Pr, 0);
		(void) fprintf(stderr, "%s: waitid() in process %d failed: %s",
		    command, (int)ppid, strerror(errno));
		return (1);
	}

	Prelease(Pr, 0);
	return (0);
}
Exemple #12
0
// the one and only one exposed stuff from this file
struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
   ELF_EHDR core_ehdr;
   ELF_EHDR exec_ehdr;
   ELF_EHDR lib_ehdr;

   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
   if (ph == NULL) {
      print_debug("can't allocate ps_prochandle\n");
      return NULL;
   }

   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
      free(ph);
      print_debug("can't allocate ps_prochandle\n");
      return NULL;
   }

   // initialize ph
   ph->ops = &core_ops;
   ph->core->core_fd   = -1;
   ph->core->exec_fd   = -1;
   ph->core->interp_fd = -1;

   // open the core file
   if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
      print_debug("can't open core file\n");
      goto err;
   }

   // read core file ELF header
   if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
      print_debug("core file is not a valid ELF ET_CORE file\n");
      goto err;
   }

   if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
      print_debug("can't open executable file\n");
      goto err;
   }

   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
      print_debug("executable file is not a valid ELF ET_EXEC file\n");
      goto err;
   }

   // process core file segments
   if (read_core_segments(ph, &core_ehdr) != true)
      goto err;

   // process exec file segments
   if (read_exec_segments(ph, &exec_ehdr) != true)
      goto err;

   // exec file is also treated like a shared object for symbol search
   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
      goto err;

   // allocate and sort maps into map_array, we need to do this
   // here because read_shared_lib_info needs to read from debuggee
   // address space
   if (sort_map_array(ph) != true)
      goto err;

   if (read_shared_lib_info(ph) != true)
      goto err;

   // sort again because we have added more mappings from shared objects
   if (sort_map_array(ph) != true)
      goto err;

   if (init_classsharing_workaround(ph) != true)
      goto err;

   return ph;

err:
   Prelease(ph);
   return NULL;
}
Exemple #13
0
static int
look(char *arg)
{
	struct ps_prochandle *Pr;
	static prcred_t *prcred = NULL;
	int gcode;

	procname = arg;		/* for perr() */

	if (prcred == NULL) {
		prcred = malloc(sizeof (prcred_t) +
			(ngroups_max - 1) * sizeof (gid_t));
		if (prcred == NULL) {
			(void) perr("malloc");
			exit(1);
		}
	}

	if ((Pr = proc_arg_grab(arg, doset ? PR_ARG_PIDS : PR_ARG_ANY,
	    PGRAB_RETAIN | PGRAB_FORCE | (doset ? 0 : PGRAB_RDONLY) |
	    PGRAB_NOSTOP, &gcode)) == NULL) {
		(void) fprintf(stderr, "%s: cannot examine %s: %s\n",
		    command, arg, Pgrab_error(gcode));
		return (1);
	}

	if (Pcred(Pr, prcred, ngroups_max) == -1) {
		(void) perr("getcred");
		Prelease(Pr, 0);
		return (1);
	}

	if (doset) {
		credupdate(prcred);
		if (Psetcred(Pr, prcred) != 0) {
			(void) perr("setcred");
			Prelease(Pr, 0);
			return (1);
		}
		Prelease(Pr, 0);
		return (0);
	}

	if (Pstate(Pr) == PS_DEAD)
		(void) printf("core of %d:\t", (int)Pstatus(Pr)->pr_pid);
	else
		(void) printf("%d:\t", (int)Pstatus(Pr)->pr_pid);

	if (!all &&
	    prcred->pr_euid == prcred->pr_ruid &&
	    prcred->pr_ruid == prcred->pr_suid)
		(void) printf("e/r/suid=%u  ", prcred->pr_euid);
	else
		(void) printf("euid=%u ruid=%u suid=%u  ",
			prcred->pr_euid, prcred->pr_ruid, prcred->pr_suid);

	if (!all &&
	    prcred->pr_egid == prcred->pr_rgid &&
	    prcred->pr_rgid == prcred->pr_sgid)
		(void) printf("e/r/sgid=%u\n", prcred->pr_egid);
	else
		(void) printf("egid=%u rgid=%u sgid=%u\n",
			prcred->pr_egid, prcred->pr_rgid, prcred->pr_sgid);

	if (prcred->pr_ngroups != 0 &&
	    (all || prcred->pr_ngroups != 1 ||
	    prcred->pr_groups[0] != prcred->pr_rgid)) {
		int i;

		(void) printf("\tgroups:");
		for (i = 0; i < prcred->pr_ngroups; i++)
			(void) printf(" %u", prcred->pr_groups[i]);
		(void) printf("\n");
	}

	Prelease(Pr, 0);
	return (0);
}
Exemple #14
0
static int
look(char *arg)
{
	struct ps_prochandle *Pr;
	int gcode;
	size_t sz;
	void *pdata;
	char *x;
	int i;
	boolean_t nodata;
	prpriv_t *ppriv;

	procname = arg;		/* for perr() */

	if ((Pr = proc_arg_grab(arg, set ? PR_ARG_PIDS : PR_ARG_ANY,
	    PGRAB_RETAIN | PGRAB_FORCE | (set ? 0 : PGRAB_RDONLY) |
	    PGRAB_NOSTOP, &gcode)) == NULL) {
		(void) fprintf(stderr, "%s: cannot examine %s: %s\n",
		    command, arg, Pgrab_error(gcode));
		return (1);
	}

	if (Ppriv(Pr, &ppriv) == -1) {
		perr(command);
		Prelease(Pr, 0);
		return (1);
	}
	sz = PRIV_PRPRIV_SIZE(ppriv);

	/*
	 * The ppriv fields are unsigned and may overflow, so check them
	 * separately.  Size must be word aligned, so check that too.
	 * Make sure size is "smallish" too.
	 */
	if ((sz & 3) || ppriv->pr_nsets == 0 ||
	    sz / ppriv->pr_nsets < ppriv->pr_setsize ||
	    ppriv->pr_infosize > sz || sz > 1024 * 1024) {
		(void) fprintf(stderr,
		    "%s: %s: bad PRNOTES section, size = %lx\n",
		    command, arg, (long)sz);
		Prelease(Pr, 0);
		Ppriv_free(Pr, ppriv);
		return (1);
	}

	if (set) {
		privupdate(ppriv, arg);
		if (Psetpriv(Pr, ppriv) != 0) {
			perr(command);
			Prelease(Pr, 0);
			Ppriv_free(Pr, ppriv);
			return (1);
		}
		Prelease(Pr, 0);
		Ppriv_free(Pr, ppriv);
		return (0);
	}

	if (Pstate(Pr) == PS_DEAD) {
		(void) printf("core '%s' of %d:\t%.70s\n",
		    arg, (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs);
		pdata = Pprivinfo(Pr);
		nodata = Pstate(Pr) == PS_DEAD && pdata == NULL;
	} else {
		(void) printf("%d:\t%.70s\n",
		    (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs);
		pdata = NULL;
		nodata = B_FALSE;
	}

	x = (char *)ppriv + sz - ppriv->pr_infosize;
	while (x < (char *)ppriv + sz) {
		/* LINTED: alignment */
		priv_info_t *pi = (priv_info_t *)x;
		priv_info_uint_t *pii;

		switch (pi->priv_info_type) {
		case PRIV_INFO_FLAGS:
			/* LINTED: alignment */
			pii = (priv_info_uint_t *)x;
			(void) printf("flags =");
			flags2str(pii->val);
			(void) putchar('\n');
			break;
		default:
			(void) fprintf(stderr, "%s: unknown priv_info: %d\n",
			    arg, pi->priv_info_type);
			break;
		}
		if (pi->priv_info_size > ppriv->pr_infosize ||
		    pi->priv_info_size <=  sizeof (priv_info_t) ||
		    (pi->priv_info_size & 3) != 0) {
			(void) fprintf(stderr, "%s: bad priv_info_size: %u\n",
			    arg, pi->priv_info_size);
			break;
		}
		x += pi->priv_info_size;
	}

	for (i = 0; i < ppriv->pr_nsets; i++) {
		extern const char *__priv_getsetbynum(const void *, int);
		const char *setnm = pdata ? __priv_getsetbynum(pdata, i) :
		    priv_getsetbynum(i);
		priv_chunk_t *pc =
		    (priv_chunk_t *)&ppriv->pr_sets[ppriv->pr_setsize * i];


		(void) printf("\t%c: ", setnm && !nodata ? *setnm : '?');
		if (!nodata) {
			extern char *__priv_set_to_str(void *,
			    const priv_set_t *, char, int);
			priv_set_t *pset = (priv_set_t *)pc;

			char *s;

			if (pdata)
				s = __priv_set_to_str(pdata, pset, ',', mode);
			else
				s = priv_set_to_str(pset, ',', mode);
			(void) puts(s);
			free(s);
		} else {
			int j;
			for (j = 0; j < ppriv->pr_setsize; j++)
				(void) printf("%08x", pc[j]);
			(void) putchar('\n');
		}
	}
	Prelease(Pr, 0);
	Ppriv_free(Pr, ppriv);
	return (0);
}
Exemple #15
0
static void attach_internal(JNIEnv* env, jobject this_obj, jstring cmdLine, jboolean isProcess) {
  jboolean isCopy;
  int gcode;
  const char* cmdLine_cstr = env->GetStringUTFChars(cmdLine, &isCopy);
  CHECK_EXCEPTION;

  // some older versions of libproc.so crash when trying to attach 32 bit
  // debugger to 64 bit core file. check and throw error.
#ifndef _LP64
  atoi(cmdLine_cstr);
  if (errno) {
     // core file
     int core_fd;
     if ((core_fd = open64(cmdLine_cstr, O_RDONLY)) >= 0) {
        Elf32_Ehdr e32;
        if (pread64(core_fd, &e32, sizeof (e32), 0) == sizeof (e32) &&
            memcmp(&e32.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0 &&
            e32.e_type == ET_CORE && e32.e_ident[EI_CLASS] == ELFCLASS64) {
              close(core_fd);
              THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use java -d64 for debugger");
        }
        close(core_fd);
     }
     // all other conditions are handled by libproc.so.
  }
#endif

  // connect to process/core
  ps_prochandle_t* ph = proc_arg_grab(cmdLine_cstr, (isProcess? PR_ARG_PIDS : PR_ARG_CORES), PGRAB_FORCE, &gcode, NULL);

  env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
  if (! ph) {
     if (gcode > 0 && gcode < sizeof(proc_arg_grab_errmsgs)/sizeof(const char*)) {
        char errMsg[ERR_MSG_SIZE];
        sprintf(errMsg, "Attach failed : %s", proc_arg_grab_errmsgs[gcode]);
        THROW_NEW_DEBUGGER_EXCEPTION(errMsg);
    } else {
        if (_libsaproc_debug && gcode == G_STRANGE) {
           perror("libsaproc DEBUG: ");
        }
        if (isProcess) {
           THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process!");
        } else {
           THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to core file!");
        }
     }
  }

  // even though libproc.so supports 64 bit debugger and 32 bit debuggee, we don't
  // support such cross-bit-debugging. check for that combination and throw error.
#ifdef _LP64
  int data_model;
  if (ps_pdmodel(ph, &data_model) != PS_OK) {
     Prelease(ph, PRELEASE_CLEAR);
     THROW_NEW_DEBUGGER_EXCEPTION("can't determine debuggee data model (ILP32? or LP64?)");
  }
  if (data_model == PR_MODEL_ILP32) {
     Prelease(ph, PRELEASE_CLEAR);
     THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
  }
#endif

  env->SetLongField(this_obj, p_ps_prochandle_ID, (jlong)(uintptr_t)ph);

  Debugger dbg;
  dbg.env = env;
  dbg.this_obj = this_obj;
  jthrowable exception = 0;
  if (! isProcess) {
    /*
     * With class sharing, shared perm. gen heap is allocated in with MAP_SHARED|PROT_READ.
     * These pages are mapped from the file "classes.jsa". MAP_SHARED pages are not dumped
     * in Solaris core.To read shared heap pages, we have to read classes.jsa file.
     */
    Pobject_iter(ph, init_classsharing_workaround, &dbg);
    exception = env->ExceptionOccurred();
    if (exception) {
      env->ExceptionClear();
      detach_internal(env, this_obj);
      env->Throw(exception);
      return;
    }
  }

  /*
   * Iterate over the process mappings looking
   * for libthread and then dlopen the appropriate
   * libthread_db and get function pointers.
   */
  Pobject_iter(ph, init_libthread_db_ptrs, &dbg);
  exception = env->ExceptionOccurred();
  if (exception) {
    env->ExceptionClear();
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
      env->Throw(exception);
    }
    return;
  }

  // init libthread_db and create thread_db agent
  p_td_init_t p_td_init = (p_td_init_t) env->GetLongField(this_obj, p_td_init_ID);
  if (p_td_init == 0) {
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
    }
    HANDLE_THREADDB_FAILURE("Did not find libthread in target process/core!");
  }

  if (p_td_init() != TD_OK) {
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
    }
    HANDLE_THREADDB_FAILURE("Can't initialize thread_db!");
  }

  p_td_ta_new_t p_td_ta_new = (p_td_ta_new_t) env->GetLongField(this_obj, p_td_ta_new_ID);

  td_thragent_t *p_td_thragent_t = 0;
  if (p_td_ta_new(ph, &p_td_thragent_t) != TD_OK) {
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
    }
    HANDLE_THREADDB_FAILURE("Can't create thread_db agent!");
  }
  env->SetLongField(this_obj, p_td_thragent_t_ID, (jlong)(uintptr_t) p_td_thragent_t);

}
Exemple #16
0
static void
dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P)
{
	dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
	dt_proc_hash_t *dph = dtp->dt_procs;
	dt_proc_notify_t *npr, **npp;
	int rflag;

	assert(dpr != NULL);

	/*
	 * If neither PR_KLC nor PR_RLC is set, then the process is stopped by
	 * an external debugger and we were waiting in dt_proc_waitrun().
	 * Leave the process in this condition using PRELEASE_HANG.
	 */
printf("dt_proc_destroy flags=%d\n", Pstatus(dpr->dpr_proc)->pr_flags);
	if (!(Pstatus(dpr->dpr_proc)->pr_flags & (PR_KLC | PR_RLC))) {
		dt_dprintf("abandoning pid %d\n", (int)dpr->dpr_pid);
		rflag = PRELEASE_HANG;
	} else {
		dt_dprintf("releasing pid %d\n", (int)dpr->dpr_pid);
		rflag = 0; /* apply kill or run-on-last-close */
	}

	if (dpr->dpr_tid) {
		/*
		 * Set the dpr_quit flag to tell the daemon thread to exit.  We
		 * send it a SIGCANCEL to poke it out of PCWSTOP or any other
		 * long-term /proc system call.  Our daemon threads have POSIX
		 * cancellation disabled, so EINTR will be the only effect.  We
		 * then wait for dpr_done to indicate the thread has exited.
		 *
		 * We can't use pthread_kill() to send SIGCANCEL because the
		 * interface forbids it and we can't use pthread_cancel()
		 * because with cancellation disabled it won't actually
		 * send SIGCANCEL to the target thread, so we use _lwp_kill()
		 * to do the job.  This is all built on evil knowledge of
		 * the details of the cancellation mechanism in libc.
		 */
		(void) pthread_mutex_lock(&dpr->dpr_lock);
		dpr->dpr_quit = B_TRUE;
#if defined(sun)
		(void) _lwp_kill(dpr->dpr_tid, SIGCANCEL);
#else
		(void) pthread_kill(dpr->dpr_tid, SIGUSR1);
#endif

		/*
		 * If the process is currently idling in dt_proc_stop(), re-
		 * enable breakpoints and poke it into running again.
		 */
		if (dpr->dpr_stop & DT_PROC_STOP_IDLE) {
			dt_proc_bpenable(dpr);
			dpr->dpr_stop &= ~DT_PROC_STOP_IDLE;
			(void) pthread_cond_broadcast(&dpr->dpr_cv);
		}

		while (!dpr->dpr_done)
			(void) pthread_cond_wait(&dpr->dpr_cv, &dpr->dpr_lock);

		(void) pthread_mutex_unlock(&dpr->dpr_lock);
	}

	/*
	 * Before we free the process structure, remove this dt_proc_t from the
	 * lookup hash, and then walk the dt_proc_hash_t's notification list
	 * and remove this dt_proc_t if it is enqueued.
	 */
	(void) pthread_mutex_lock(&dph->dph_lock);
	(void) dt_proc_lookup(dtp, P, B_TRUE);
	npp = &dph->dph_notify;

	while ((npr = *npp) != NULL) {
		if (npr->dprn_dpr == dpr) {
			*npp = npr->dprn_next;
			dt_free(dtp, npr);
		} else {
			npp = &npr->dprn_next;
		}
	}

	(void) pthread_mutex_unlock(&dph->dph_lock);

	/*
	 * Remove the dt_proc_list from the LRU list, release the underlying
	 * libproc handle, and free our dt_proc_t data structure.
	 */
	if (dpr->dpr_cacheable) {
		assert(dph->dph_lrucnt != 0);
		dph->dph_lrucnt--;
	}

	dt_list_delete(&dph->dph_lrulist, dpr);
	Prelease(dpr->dpr_proc, rflag);
	dt_free(dtp, dpr);
}
Exemple #17
0
static int
look(char *arg)
{
	int gcode;
	int gcode2;
	pstatus_t pstatus;
	psinfo_t psinfo;
	int flags;
	sigset_t sigmask;
	fltset_t fltmask;
	sysset_t entryset;
	sysset_t exitset;
	uint32_t sigtrace, sigtrace1, sigtrace2, fltbits;
	uint32_t sigpend, sigpend1, sigpend2;
	uint32_t *bits;
	char buf[PRSIGBUFSZ];
	look_arg_t lookarg;

	if ((Pr = proc_arg_xgrab(arg, NULL, PR_ARG_ANY,
	    PGRAB_RETAIN | PGRAB_FORCE | PGRAB_RDONLY | PGRAB_NOSTOP, &gcode,
	    &lookarg.lwps)) == NULL) {
		if (gcode == G_NOPROC &&
		    proc_arg_psinfo(arg, PR_ARG_PIDS, &psinfo, &gcode2) > 0 &&
		    psinfo.pr_nlwp == 0) {
			(void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid);
			return (0);
		}
		(void) fprintf(stderr, "%s: cannot examine %s: %s\n",
		    command, arg, Pgrab_error(gcode));
		return (1);
	}

	(void) memcpy(&pstatus, Pstatus(Pr), sizeof (pstatus_t));
	(void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
	proc_unctrl_psinfo(&psinfo);

	if (psinfo.pr_nlwp == 0) {
		(void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid);
		Prelease(Pr, PRELEASE_RETAIN);
		return (0);
	}

	is64 = (pstatus.pr_dmodel == PR_MODEL_LP64);

	sigmask = pstatus.pr_sigtrace;
	fltmask = pstatus.pr_flttrace;
	entryset = pstatus.pr_sysentry;
	exitset = pstatus.pr_sysexit;

	if (Pstate(Pr) == PS_DEAD) {
		(void) printf("core '%s' of %d:\t%.70s\n",
		    arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
	} else {
		(void) printf("%d:\t%.70s\n",
		    (int)psinfo.pr_pid, psinfo.pr_psargs);
	}

	(void) printf("\tdata model = %s", is64? "_LP64" : "_ILP32");
	if ((flags = (pstatus.pr_flags & PROCFLAGS)) != 0)
		(void) printf("  flags = %s", prflags(flags));
	(void) printf("\n");

	fltbits = *((uint32_t *)&fltmask);
	if (fltbits)
		(void) printf("\tflttrace = 0x%.8x\n", fltbits);

#if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)	/* assumption */
	sigtrace = *((uint32_t *)&sigmask);
	sigtrace1 = *((uint32_t *)&sigmask + 1);
	sigtrace2 = *((uint32_t *)&sigmask + 2);
#else
#error "fix me: MAXSIG out of bounds"
#endif
	if (sigtrace | sigtrace1 | sigtrace2)
		(void) printf("\tsigtrace = 0x%.8x 0x%.8x 0x%.8x\n\t    %s\n",
		    sigtrace, sigtrace1, sigtrace2,
		    proc_sigset2str(&sigmask, "|", 1, buf, sizeof (buf)));

	bits = ((uint32_t *)&entryset);
	if (bits[0] | bits[1] | bits[2] | bits[3] |
	    bits[4] | bits[5] | bits[6] | bits[7])
		(void) printf(
		    "\tentryset = "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
		    "\t           "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
		    bits[0], bits[1], bits[2], bits[3],
		    bits[4], bits[5], bits[6], bits[7]);

	bits = ((uint32_t *)&exitset);
	if (bits[0] | bits[1] | bits[2] | bits[3] |
	    bits[4] | bits[5] | bits[6] | bits[7])
		(void) printf(
		    "\texitset  = "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
		    "\t           "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
		    bits[0], bits[1], bits[2], bits[3],
		    bits[4], bits[5], bits[6], bits[7]);

#if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)	/* assumption */
	sigpend  = *((uint32_t *)&pstatus.pr_sigpend);
	sigpend1 = *((uint32_t *)&pstatus.pr_sigpend + 1);
	sigpend2 = *((uint32_t *)&pstatus.pr_sigpend + 2);
#else
#error "fix me: MAXSIG out of bounds"
#endif
	if (sigpend | sigpend1 | sigpend2)
		(void) printf("\tsigpend = 0x%.8x,0x%.8x,0x%.8x\n",
		    sigpend, sigpend1, sigpend2);

	lookarg.pflags = pstatus.pr_flags;
	lookarg.count = 0;
	(void) Plwp_iter_all(Pr, (proc_lwp_all_f *)lwplook, &lookarg);

	if (lookarg.count == 0)
		(void) printf("No matching lwps found");

	(void) printf("\n");
	Prelease(Pr, PRELEASE_RETAIN);

	return (0);
}
Exemple #18
0
int
main(int argc, char **argv)
{
    int rflag = 0, sflag = 0, xflag = 0, Fflag = 0;
    int errflg = 0, Sflag = 0;
    int rc = 0;
    int opt;
    const char *bar8 = "-------";
    const char *bar16 = "----------";
    const char *bar;
    struct rlimit rlim;
    struct stat64 statbuf;
    char buf[128];
    int mapfd;
    int prg_gflags = PGRAB_RDONLY;
    int prr_flags = 0;
    boolean_t use_agent_lwp = B_FALSE;

    if ((command = strrchr(argv[0], '/')) != NULL)
        command++;
    else
        command = argv[0];

    while ((opt = getopt(argc, argv, "arsxSlLFA:")) != EOF) {
        switch (opt) {
        case 'a':		/* include shared mappings in -[xS] */
            aflag = 1;
            break;
        case 'r':		/* show reserved mappings */
            rflag = 1;
            break;
        case 's':		/* show hardware page sizes */
            sflag = 1;
            break;
        case 'S':		/* show swap reservations */
            Sflag = 1;
            break;
        case 'x':		/* show extended mappings */
            xflag = 1;
            break;
        case 'l':		/* show unresolved link map names */
            lflag = 1;
            break;
        case 'L':		/* show lgroup information */
            Lflag = 1;
            use_agent_lwp = B_TRUE;
            break;
        case 'F':		/* force grabbing (no O_EXCL) */
            Fflag = PGRAB_FORCE;
            break;
        case 'A':
            if (parse_addr_range(optarg, &start_addr, &end_addr)
                    != 0)
                errflg++;
            break;
        default:
            errflg = 1;
            break;
        }
    }

    argc -= optind;
    argv += optind;

    if ((Sflag && (xflag || rflag || sflag)) || (xflag && rflag) ||
            (aflag && (!xflag && !Sflag)) ||
            (Lflag && (xflag || Sflag))) {
        errflg = 1;
    }

    if (errflg || argc <= 0) {
        (void) fprintf(stderr,
                       "usage:\t%s [-rslF] [-A start[,end]] { pid | core } ...\n",
                       command);
        (void) fprintf(stderr,
                       "\t\t(report process address maps)\n");
        (void) fprintf(stderr,
                       "\t%s -L [-rslF] [-A start[,end]] pid ...\n", command);
        (void) fprintf(stderr,
                       "\t\t(report process address maps lgroups mappings)\n");
        (void) fprintf(stderr,
                       "\t%s -x [-aslF] [-A start[,end]] pid ...\n", command);
        (void) fprintf(stderr,
                       "\t\t(show resident/anon/locked mapping details)\n");
        (void) fprintf(stderr,
                       "\t%s -S [-alF] [-A start[,end]] { pid | core } ...\n",
                       command);
        (void) fprintf(stderr,
                       "\t\t(show swap reservations)\n\n");
        (void) fprintf(stderr,
                       "\t-a: include shared mappings in -[xS] summary\n");
        (void) fprintf(stderr,
                       "\t-r: show reserved address maps\n");
        (void) fprintf(stderr,
                       "\t-s: show hardware page sizes\n");
        (void) fprintf(stderr,
                       "\t-l: show unresolved dynamic linker map names\n");
        (void) fprintf(stderr,
                       "\t-F: force grabbing of the target process\n");
        (void) fprintf(stderr,
                       "\t-L: show lgroup mappings\n");
        (void) fprintf(stderr,
                       "\t-A start,end: limit output to the specified range\n");
        return (2);
    }

    /*
     * Make sure we'll have enough file descriptors to handle a target
     * that has many many mappings.
     */
    if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
        rlim.rlim_cur = rlim.rlim_max;
        (void) setrlimit(RLIMIT_NOFILE, &rlim);
        (void) enable_extended_FILE_stdio(-1, -1);
    }

    /*
     * The implementation of -L option creates an agent LWP in the target
     * process address space. The agent LWP issues meminfo(2) system calls
     * on behalf of the target process. If we are interrupted prematurely,
     * the target process remains in the stopped state with the agent still
     * attached to it. To prevent such situation we catch signals from
     * terminal and terminate gracefully.
     */
    if (use_agent_lwp) {
        /*
         * Buffer output to stdout, stderr while process is grabbed.
         * Prevents infamous deadlocks due to pmap `pgrep xterm` and
         * other variants.
         */
        (void) proc_initstdio();

        prg_gflags = PGRAB_RETAIN | Fflag;
        prr_flags = PRELEASE_RETAIN;

        if (sigset(SIGHUP, SIG_IGN) == SIG_DFL)
            (void) sigset(SIGHUP, intr);
        if (sigset(SIGINT, SIG_IGN) == SIG_DFL)
            (void) sigset(SIGINT, intr);
        if (sigset(SIGQUIT, SIG_IGN) == SIG_DFL)
            (void) sigset(SIGQUIT, intr);
        (void) sigset(SIGPIPE, intr);
        (void) sigset(SIGTERM, intr);
    }

    while (argc-- > 0) {
        char *arg;
        int gcode;
        psinfo_t psinfo;
        int tries = 0;

        if (use_agent_lwp)
            (void) proc_flushstdio();

        if ((Pr = proc_arg_grab(arg = *argv++, PR_ARG_ANY,
                                prg_gflags, &gcode)) == NULL) {
            (void) fprintf(stderr, "%s: cannot examine %s: %s\n",
                           command, arg, Pgrab_error(gcode));
            rc++;
            continue;
        }

        procname = arg;		/* for perr() */

        addr_width = (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) ? 16 : 8;
        size_width = (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) ? 11 : 8;
        bar = addr_width == 8 ? bar8 : bar16;
        (void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
        proc_unctrl_psinfo(&psinfo);

        if (Pstate(Pr) != PS_DEAD) {
            (void) snprintf(buf, sizeof (buf),
                            "/proc/%d/map", (int)psinfo.pr_pid);
            if ((mapfd = open(buf, O_RDONLY)) < 0) {
                (void) fprintf(stderr, "%s: cannot "
                               "examine %s: lost control of "
                               "process\n", command, arg);
                rc++;
                Prelease(Pr, prr_flags);
                continue;
            }
        } else {
            mapfd = -1;
        }

again:
        map_count = 0;

        if (Pstate(Pr) == PS_DEAD) {
            (void) printf("core '%s' of %d:\t%.70s\n",
                          arg, (int)psinfo.pr_pid, psinfo.pr_psargs);

            if (rflag || sflag || xflag || Sflag || Lflag) {
                (void) printf("  -%c option is not compatible "
                              "with core files\n", xflag ? 'x' :
                              sflag ? 's' : rflag ? 'r' :
                              Lflag ? 'L' : 'S');
                Prelease(Pr, prr_flags);
                rc++;
                continue;
            }

        } else {
            (void) printf("%d:\t%.70s\n",
                          (int)psinfo.pr_pid, psinfo.pr_psargs);
        }

        if (!(Pstatus(Pr)->pr_flags & PR_ISSYS)) {
            struct totals t;

            /*
             * Since we're grabbing the process readonly, we need
             * to make sure the address space doesn't change during
             * execution.
             */
            if (Pstate(Pr) != PS_DEAD) {
                if (tries++ == MAX_TRIES) {
                    Prelease(Pr, prr_flags);
                    (void) close(mapfd);
                    (void) fprintf(stderr, "%s: cannot "
                                   "examine %s: address space is "
                                   "changing\n", command, arg);
                    continue;
                }

                if (fstat64(mapfd, &statbuf) != 0) {
                    Prelease(Pr, prr_flags);
                    (void) close(mapfd);
                    (void) fprintf(stderr, "%s: cannot "
                                   "examine %s: lost control of "
                                   "process\n", command, arg);
                    continue;
                }
            }

            nstacks = psinfo.pr_nlwp * 2;
            stacks = calloc(nstacks, sizeof (stacks[0]));
            if (stacks != NULL) {
                int n = 0;
                (void) Plwp_iter(Pr, getstack, &n);
                qsort(stacks, nstacks, sizeof (stacks[0]),
                      cmpstacks);
            }

            (void) memset(&t, 0, sizeof (t));

            if (Pgetauxval(Pr, AT_BASE) != -1L &&
                    Prd_agent(Pr) == NULL) {
                (void) fprintf(stderr, "%s: warning: "
                               "librtld_db failed to initialize; "
                               "shared library information will not be "
                               "available\n", command);
            }

            /*
             * Gather data
             */
            if (xflag)
                rc += xmapping_iter(Pr, gather_xmap, NULL, 0);
            else if (Sflag)
                rc += xmapping_iter(Pr, gather_xmap, NULL, 1);
            else {
                if (rflag)
                    rc += rmapping_iter(Pr, gather_map,
                                        NULL);
                else if (sflag)
                    rc += xmapping_iter(Pr, gather_xmap,
                                        NULL, 0);
                else if (lflag)
                    rc += Pmapping_iter(Pr,
                                        gather_map, NULL);
                else
                    rc += Pmapping_iter_resolved(Pr,
                                                 gather_map, NULL);
            }

            /*
             * Ensure mappings are consistent.
             */
            if (Pstate(Pr) != PS_DEAD) {
                struct stat64 newbuf;

                if (fstat64(mapfd, &newbuf) != 0 ||
                        memcmp(&newbuf.st_mtim, &statbuf.st_mtim,
                               sizeof (newbuf.st_mtim)) != 0) {
                    if (stacks != NULL) {
                        free(stacks);
                        stacks = NULL;
                    }
                    goto again;
                }
            }

            /*
             * Display data.
             */
            if (xflag) {
                (void) printf("%*s%*s%*s%*s%*s "
                              "%sMode   Mapped File\n",
                              addr_width, "Address",
                              size_width, "Kbytes",
                              size_width, "RSS",
                              size_width, "Anon",
                              size_width, "Locked",
                              sflag ? "Pgsz " : "");

                rc += iter_xmap(sflag ?  look_xmap :
                                look_xmap_nopgsz, &t);

                (void) printf("%s%s %s %s %s %s\n",
                              addr_width == 8 ? "-" : "------",
                              bar, bar, bar, bar, bar);

                (void) printf("%stotal Kb", addr_width == 16 ?
                              "        " : "");

                printK(t.total_size, size_width);
                printK(t.total_rss, size_width);
                printK(t.total_anon, size_width);
                printK(t.total_locked, size_width);

                (void) printf("\n");

            } else if (Sflag) {
                (void) printf("%*s%*s%*s Mode"
                              " Mapped File\n",
                              addr_width, "Address",
                              size_width, "Kbytes",
                              size_width, "Swap");

                rc += iter_xmap(look_xmap_nopgsz, &t);

                (void) printf("%s%s %s %s\n",
                              addr_width == 8 ? "-" : "------",
                              bar, bar, bar);

                (void) printf("%stotal Kb", addr_width == 16 ?
                              "        " : "");

                printK(t.total_size, size_width);
                printK(t.total_swap, size_width);

                (void) printf("\n");

            } else {

                if (rflag) {
                    rc += iter_map(look_map, &t);
                } else if (sflag) {
                    if (Lflag) {
                        (void) printf("%*s %*s %4s"
                                      " %-6s %s %s\n",
                                      addr_width, "Address",
                                      size_width,
                                      "Bytes", "Pgsz", "Mode ",
                                      "Lgrp", "Mapped File");
                        rc += iter_xmap(look_smap, &t);
                    } else {
                        (void) printf("%*s %*s %4s"
                                      " %-6s %s\n",
                                      addr_width, "Address",
                                      size_width,
                                      "Bytes", "Pgsz", "Mode ",
                                      "Mapped File");
                        rc += iter_xmap(look_smap, &t);
                    }
                } else {
                    rc += iter_map(look_map, &t);
                }

                (void) printf(" %stotal  %*luK\n",
                              addr_width == 16 ?
                              "        " : "",
                              size_width, t.total_size);
            }

            if (stacks != NULL) {
                free(stacks);
                stacks = NULL;
            }

        }

        Prelease(Pr, prr_flags);
        if (mapfd != -1)
            (void) close(mapfd);
    }

    if (use_agent_lwp)
        (void) proc_finistdio();

    return (rc);
}
Exemple #19
0
int
main(int argc, char **argv)
{
	secflagdelta_t act;
	psecflagwhich_t which = PSF_INHERIT;
	int ret = 0;
	int pgrab_flags = PGRAB_RDONLY;
	int opt;
	char *idtypename = NULL;
	idtype_t idtype = P_PID;
	boolean_t usage = B_FALSE;
	boolean_t e_flag = B_FALSE;
	boolean_t l_flag = B_FALSE;
	boolean_t s_flag = B_FALSE;
	int errc = 0;

	while ((opt = getopt(argc, argv, "eFi:ls:")) != -1) {
		switch (opt) {
		case 'e':
			e_flag = B_TRUE;
			break;
		case 'F':
			pgrab_flags |= PGRAB_FORCE;
			break;
		case 'i':
			idtypename = optarg;
			break;
		case 's':
			s_flag = B_TRUE;
			if ((strlen(optarg) >= 2) &&
			    ((optarg[1] == '='))) {
				switch (optarg[0]) {
				case 'L':
					which = PSF_LOWER;
					break;
				case 'U':
					which = PSF_UPPER;
					break;
				case 'I':
					which = PSF_INHERIT;
					break;
				case 'E':
					errx(1, "the effective flags cannot "
					    "be changed", optarg[0]);
				default:
					errx(1, "unknown security flag "
					    "set: '%c'", optarg[0]);
				}

				optarg += 2;
			}

			if (secflags_parse(NULL, optarg, &act) == -1)
				errx(1, "couldn't parse security flags: %s",
				    optarg);
			break;
		case 'l':
			l_flag = B_TRUE;
			break;
		default:
			usage = B_TRUE;
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (l_flag && ((idtypename != NULL) || s_flag || (argc != 0)))
		usage = B_TRUE;
	if ((idtypename != NULL) && !s_flag)
		usage = B_TRUE;
	if (e_flag && !s_flag)
		usage = B_TRUE;
	if (!l_flag && argc <= 0)
		usage = B_TRUE;

	if (usage) {
		(void) fprintf(stderr,
		    gettext("usage:\t%s [-F] { pid | core } ...\n"),
		    __progname);
		(void) fprintf(stderr,
		    gettext("\t%s -s spec [-i idtype] id ...\n"),
		    __progname);
		(void) fprintf(stderr,
		    gettext("\t%s -s spec -e command [arg]...\n"),
		    __progname);
		(void) fprintf(stderr, gettext("\t%s -l\n"), __progname);
		return (2);
	}

	if (l_flag) {
		secflag_t i;
		const char *name;

		for (i = 0; (name = secflag_to_str(i)) != NULL; i++)
			(void) printf("%s\n", name);
		return (0);
	} else if (s_flag && e_flag) {
		/*
		 * Don't use the strerror() message for EPERM, "Not Owner"
		 * which is misleading.
		 */
		errc = psecflags(P_PID, P_MYID, which, &act);
		switch (errc) {
		case 0:
			break;
		case EPERM:
			errx(1, gettext("failed setting "
			    "security-flags: Permission denied"));
			break;
		default:
			err(1, gettext("failed setting security-flags"));
		}

		(void) execvp(argv[0], &argv[0]);
		err(1, "%s", argv[0]);
	} else if (s_flag) {
		int i;
		id_t id;

		if (idtypename != NULL)
			if (str2idtype(idtypename, &idtype) == -1)
				errx(1, gettext("No such id type: '%s'"),
				    idtypename);

		for (i = 0; i < argc; i++) {
			if ((id = getid(idtype, argv[i])) == (id_t)-1) {
				errx(1, gettext("invalid or non-existent "
				    "identifier: '%s'"), argv[i]);
			}

			/*
			 * Don't use the strerror() message for EPERM, "Not
			 * Owner" which is misleading.
			 */
			if (psecflags(idtype, id, which, &act) != 0) {
				switch (errno) {
				case EPERM:
					errx(1, gettext("failed setting "
					    "security-flags: "
					    "Permission denied"));
					break;
				default:
					err(1, gettext("failed setting "
					    "security-flags"));
				}
			}
		}

		return (0);
	}

	/* Display the flags for the given pids */
	while (argc-- > 0) {
		struct ps_prochandle *Pr;
		const char *arg;
		psinfo_t psinfo;
		prsecflags_t *psf;
		int gcode;

		if ((Pr = proc_arg_grab(arg = *argv++, PR_ARG_ANY,
		    pgrab_flags, &gcode)) == NULL) {
			warnx(gettext("cannot examine %s: %s"),
			    arg, Pgrab_error(gcode));
			ret = 1;
			continue;
		}

		(void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
		proc_unctrl_psinfo(&psinfo);

		if (Pstate(Pr) == PS_DEAD) {
			(void) printf(gettext("core '%s' of %d:\t%.70s\n"),
			    arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
		} else {
			(void) printf("%d:\t%.70s\n",
			    (int)psinfo.pr_pid, psinfo.pr_psargs);
		}

		if (Psecflags(Pr, &psf) != 0)
			err(1, gettext("cannot read secflags of %s"), arg);

		print_flags("E", psf->pr_effective);
		print_flags("I", psf->pr_inherit);
		print_flags("L", psf->pr_lower);
		print_flags("U", psf->pr_upper);

		Psecflags_free(psf);
		Prelease(Pr, 0);
	}

	return (ret);
}