Beispiel #1
0
static inline cdx_void QueueNodeEntityDecRef(AwPoolT *pool, struct CdxQueueNodeEntityS *entity)
{
    if (CdxAtomicDec(&entity->ref) == 0)
    {
        Pfree(pool, entity);
    }
}
Beispiel #2
0
cdx_void CdxQueueDestroy(CdxQueueT *queue)
{
    struct CdxQueueImplS *impl;
//    struct CdxQueueNodeEntityS *dummy;
    
    CDX_ASSERT(queue);
    impl = CdxContainerOf(queue, struct CdxQueueImplS, base);

    impl->enablePush = CDX_FALSE;
    
    impl->enablePop = CDX_FALSE;
    CDX_LOG_ASSERT(impl->front == impl->rear, "queue not empty");

    QueueNodeEntityDecRef(impl->pool, impl->front);
    Pfree(impl->pool, impl);

    return ;
}
Beispiel #3
0
static int
stop(char *arg)
{
	int gcode;
	int rc = 0;

	if ((P = proc_arg_xgrab(arg, NULL, PR_ARG_PIDS, PGRAB_RETAIN |
	    PGRAB_NOSTOP | PGRAB_FORCE, &gcode, &lwps)) == NULL) {
		(void) fprintf(stderr, "%s: cannot control %s: %s\n",
		    command, arg, Pgrab_error(gcode));
		return (1);
	} else if (lwps != NULL) {
		/*
		 * The user has provided an lwp specification.  Let's consider
		 * the lwp specification as a mask.  We iterate over all lwps in
		 * the process and stop every lwp, which matches the mask.  If
		 * there is no lwp matching the mask or an error occured during
		 * the iteration, set the return code to 1 as indication of an
		 * error.
		 */
		int lwpcount = 0;

		(void) Plwp_iter_all(P, (proc_lwp_all_f *)lwpstop, &lwpcount);
		if (lwpcount == 0) {
			(void) fprintf(stderr, "%s: cannot control %s:"
			    " no matching LWPs found\n", command, arg);
			rc = 1;
		} else if (lwpcount == -1)
			rc = 1;
	} else {
		(void) Pdstop(P);	/* Stop the process. */
	}

	/*
	 * Prelease could change the tracing flags, use Pfree and unset
	 * run-on-last-close flag to prevent the process being set running
	 * after detaching from it.
	 */
	(void) Punsetflags(P, PR_RLC);
	Pfree(P);
	return (rc);
}
Beispiel #4
0
struct ps_prochandle *
Pgrab_file(const char *fname, int *perr)
{
	struct ps_prochandle *P = NULL;
	char buf[PATH_MAX];
	GElf_Ehdr ehdr;
	Elf *elf = NULL;
	size_t phnum;
	file_info_t *fp = NULL;
	int fd;
	int i;

	if ((fd = open64(fname, O_RDONLY)) < 0) {
		dprintf("couldn't open file");
		*perr = (errno == ENOENT) ? G_NOEXEC : G_STRANGE;
		return (NULL);
	}

	if (elf_version(EV_CURRENT) == EV_NONE) {
		dprintf("libproc ELF version is more recent than libelf");
		*perr = G_ELF;
		goto err;
	}

	if ((P = calloc(1, sizeof (struct ps_prochandle))) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	(void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
	P->state = PS_IDLE;
	P->pid = (pid_t)-1;
	P->asfd = fd;
	P->ctlfd = -1;
	P->statfd = -1;
	P->agentctlfd = -1;
	P->agentstatfd = -1;
	P->info_valid = -1;
	P->ops = &P_idle_ops;
	Pinitsym(P);

	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
		*perr = G_ELF;
		return (NULL);
	}

	/*
	 * Construct a file_info_t that corresponds to this file.
	 */
	if ((fp = calloc(1, sizeof (file_info_t))) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	if (*fname == '/') {
		(void) strncpy(fp->file_pname, fname, sizeof (fp->file_pname));
	} else {
		size_t sz;

		if (getcwd(fp->file_pname, sizeof (fp->file_pname) - 1) ==
		    NULL) {
			*perr = G_STRANGE;
			goto err;
		}

		sz = strlen(fp->file_pname);
		(void) snprintf(&fp->file_pname[sz],
		    sizeof (fp->file_pname) - sz, "/%s", fname);
	}

	fp->file_fd = fd;
	fp->file_lo->rl_lmident = LM_ID_BASE;
	if ((fp->file_lname = strdup(fp->file_pname)) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}
	fp->file_lbase = basename(fp->file_lname);

	if ((P->execname = strdup(fp->file_pname)) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	P->num_files++;
	list_link(fp, &P->file_head);

	if (gelf_getehdr(elf, &ehdr) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	if (elf_getphdrnum(elf, &phnum) == -1) {
		*perr = G_STRANGE;
		goto err;
	}

	dprintf("Pgrab_file: program header count = %lu\n", (ulong_t)phnum);

	/*
	 * Sift through the program headers making the relevant maps.
	 */
	for (i = 0; i < phnum; i++) {
		GElf_Phdr phdr, *php;

		if ((php = gelf_getphdr(elf, i, &phdr)) == NULL) {
			*perr = G_STRANGE;
			goto err;
		}

		if (php->p_type != PT_LOAD)
			continue;

		if (idle_add_mapping(P, php, fp) != 0) {
			*perr = G_STRANGE;
			goto err;
		}
	}
	Psort_mappings(P);

	(void) elf_end(elf);

	P->map_exec = fp->file_map;

	P->status.pr_flags = PR_STOPPED;
	P->status.pr_nlwp = 0;
	P->status.pr_pid = (pid_t)-1;
	P->status.pr_ppid = (pid_t)-1;
	P->status.pr_pgid = (pid_t)-1;
	P->status.pr_sid = (pid_t)-1;
	P->status.pr_taskid = (taskid_t)-1;
	P->status.pr_projid = (projid_t)-1;
	P->status.pr_zoneid = (zoneid_t)-1;
	switch (ehdr.e_ident[EI_CLASS]) {
	case ELFCLASS32:
		P->status.pr_dmodel = PR_MODEL_ILP32;
		break;
	case ELFCLASS64:
		P->status.pr_dmodel = PR_MODEL_LP64;
		break;
	default:
		*perr = G_FORMAT;
		goto err;
	}

	/*
	 * Pfindobj() checks what zone a process is associated with, so
	 * we call it after initializing pr_zoneid to -1.  This ensures
	 * we don't get associated with any zone on the system.
	 */
	if (Pfindobj(P, fp->file_lname, buf, sizeof (buf)) != NULL) {
		free(P->execname);
		P->execname = strdup(buf);
		if ((fp->file_rname = strdup(buf)) != NULL)
			fp->file_rbase = basename(fp->file_rname);
	}

	/*
	 * The file and map lists are complete, and will never need to be
	 * adjusted.
	 */
	P->info_valid = 1;

	return (P);
err:
	(void) close(fd);
	if (P != NULL)
		Pfree(P);
	if (elf != NULL)
		(void) elf_end(elf);
	return (NULL);
}