예제 #1
0
/*
 * Wait for the specified process to hit a breakpoint at the specified symbol.
 */
static void
verify_bkpt(struct proc_handle *phdl, GElf_Sym *sym, const char *symname,
    const char *mapname)
{
	char mapbname[MAXPATHLEN], *name;
	GElf_Sym tsym;
	prmap_t *map;
	size_t namesz;
	u_long addr;
	int error, state;

	state = proc_wstatus(phdl);
	ATF_REQUIRE_EQ_MSG(state, PS_STOP, "process has state %d", state);

	/* Get the program counter and decrement it. */
	error = proc_regget(phdl, REG_PC, &addr);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to obtain PC for '%s'",
	    target_prog_file);
	proc_bkptregadj(&addr);

	/*
	 * Make sure the PC matches the expected value obtained from the symbol
	 * definition we looked up earlier.
	 */
	ATF_CHECK_EQ_MSG(addr, sym->st_value,
	    "program counter 0x%lx doesn't match expected value 0x%jx",
	    addr, (uintmax_t)sym->st_value);

	/*
	 * Ensure we can look up the r_debug_state symbol using its starting
	 * address and that the resulting symbol matches the one we found using
	 * a name lookup.
	 */
	namesz = strlen(symname) + 1;
	name = malloc(namesz);
	ATF_REQUIRE(name != NULL);

	error = proc_addr2sym(phdl, addr, name, namesz, &tsym);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up symbol at 0x%lx", addr);
	ATF_REQUIRE_EQ(memcmp(sym, &tsym, sizeof(*sym)), 0);
	ATF_REQUIRE_EQ_MSG(strcmp(symname, name), 0,
	    "expected symbol name '%s' doesn't match '%s'", symname, name);
	free(name);

	map = proc_addr2map(phdl, addr);
	ATF_REQUIRE_MSG(map != NULL, "failed to look up map for address 0x%lx",
	    addr);
	basename_r(map->pr_mapname, mapbname);
	ATF_REQUIRE_EQ_MSG(strcmp(mapname, mapbname), 0,
	    "expected map name '%s' doesn't match '%s'", mapname, mapbname);
}
예제 #2
0
/*
 * Step over the breakpoint.
 */
int
proc_bkptexec(struct proc_handle *phdl, unsigned long saved)
{
	unsigned long pc;
	unsigned long samesaved;
	int status;

	if (proc_regget(phdl, REG_PC, &pc) < 0) {
		warn("ERROR: couldn't get PC register");
		return (-1);
	}
	proc_bkptregadj(&pc);
	if (proc_bkptdel(phdl, pc, saved) < 0) {
		warn("ERROR: couldn't delete breakpoint");
		return (-1);
	}
	/*
	 * Go back in time and step over the new instruction just
	 * set up by proc_bkptdel().
	 */
	proc_regset(phdl, REG_PC, pc);
	if (ptrace(PT_STEP, proc_getpid(phdl), (caddr_t)1, 0) < 0) {
		warn("ERROR: ptrace step failed");
		return (-1);
	}
	proc_wstatus(phdl);
	status = proc_getwstat(phdl);
	if (!WIFSTOPPED(status)) {
		warn("ERROR: don't know why process stopped");
		return (-1);
	}
	/*
	 * Restore the breakpoint. The saved instruction should be
	 * the same as the one that we were passed in.
	 */
	if (proc_bkptset(phdl, pc, &samesaved) < 0) {
		warn("ERROR: couldn't restore breakpoint");
		return (-1);
	}
	assert(samesaved == saved);

	return (0);
}
예제 #3
0
static void
dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
{
#ifdef illumos
	const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp;
#else
	unsigned long pc;
#endif
	dt_bkpt_t *dbp;

	assert(DT_MUTEX_HELD(&dpr->dpr_lock));

#ifndef illumos
	proc_regget(dpr->dpr_proc, REG_PC, &pc);
	proc_bkptregadj(&pc);
#endif

	for (dbp = dt_list_next(&dpr->dpr_bps);
	    dbp != NULL; dbp = dt_list_next(dbp)) {
#ifdef illumos
		if (psp->pr_reg[R_PC] == dbp->dbp_addr)
			break;
#else
		if (pc == dbp->dbp_addr)
			break;
#endif
	}

	if (dbp == NULL) {
		dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
#ifdef illumos
		    (int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]);
#else
		    (int)dpr->dpr_pid, pc);
#endif
		return;
	}