Exemplo n.º 1
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);
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
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);

}
Exemplo n.º 6
0
/*
 * Class:     sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:    attach0
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_attach0
  (JNIEnv *env, jobject this_obj, jstring cmdLine) {
  jboolean isCopy;
  int gcode;
  const char* cmdLine_cstr = env->GetStringUTFChars(cmdLine, &isCopy);
  CHECK_EXCEPTION;

  struct ps_prochandle* Pr = proc_arg_grab(cmdLine_cstr, PR_ARG_ANY, PGRAB_FORCE, &gcode);
  env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
  if(! Pr) 
    THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process/core file!");

  env->SetLongField(this_obj, ps_prochandle_ptr_ID, (jlong) Pr);

  // initialize libthread_db pointers
  
  /*
   * Iterate over the process mappings looking
   * for libthread and then dlopen the appropriate
   * libthread_db and get pointers to functions.
   */

  Debugger dbg;
  dbg.env = env;
  dbg.obj = this_obj;
  (void) Pobject_iter(Pr, object_iter, &dbg);
  CHECK_EXCEPTION;
  
  // get the user level threads info
  td_thragent_t *Tap = 0;
  p_td_init_t p_td_init = (p_td_init_t) env->GetLongField(this_obj, p_td_init_ID);

  if (p_td_init == 0)
     return;

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

  if (p_td_init() != TD_OK) 
     THROW_NEW_DEBUGGER_EXCEPTION("Can't initialize thread_db!");

  if (p_td_ta_new(Pr, &Tap) != TD_OK)
     THROW_NEW_DEBUGGER_EXCEPTION("Can't create thread_db agent!");
 
  /*
   * Iterate over all threads, calling:
   *   thr_stack(td_thrhandle_t *Thp, NULL);
   * for each one to generate the list of threads.
   */

  p_td_ta_thr_iter_t p_td_ta_thr_iter = (p_td_ta_thr_iter_t)
                                     env->GetLongField(this_obj, p_td_ta_thr_iter_ID);

  (void) p_td_ta_thr_iter(Tap, thr_stack, &dbg,
                          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
                           TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
  CHECK_EXCEPTION;

  p_td_ta_delete_t p_td_ta_delete = (p_td_ta_delete_t)
                                     env->GetLongField(this_obj, p_td_ta_delete_ID);
  (void) p_td_ta_delete(Tap);
  
  // Part of workaround for 4705086.

  /* 
   * iterate over maps of the process/core to get first
   * libjvm[_g].so mapping.
   */

  Pmapping_iter(Pr, iterate_map, &dbg);
  CHECK_EXCEPTION;

  /*
   * Get libjvm[_g].so text size. First location after the end of text segment
   * is marked by the global reserved symbol '_etext' in any ELF file.
   * Please refer to page 53 of "Linkers and Libraries Guide - 816-0559".
   */

  psaddr_t etext_addr;
  if (ps_pglobal_lookup(Pr, "libjvm.so", "_etext", &etext_addr) != PS_OK) {
      // try the debug version
      if (ps_pglobal_lookup(Pr, "libjvm_g.so", "_etext", &etext_addr) != PS_OK) 
         THROW_NEW_DEBUGGER_EXCEPTION("Can't get end of text address of libjvm!");
  }

  // now calculate and set libjvm text size.
  jlong libjvm_text_start = env->GetLongField(this_obj, libjvm_text_start_ID);
  env->SetLongField(this_obj, libjvm_text_size_ID, (jlong) (etext_addr - libjvm_text_start));
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
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);
}