static void
db_show_callout_bucket(struct callout_cpu *cc, struct callout_circq *bucket)
{
	callout_impl_t *c;
	db_expr_t offset;
	const char *name;
	static char question[] = "?";
	int b;

	if (CIRCQ_EMPTY(bucket))
		return;

	for (c = CIRCQ_FIRST(bucket); /*nothing*/; c = CIRCQ_NEXT(&c->c_list)) {
		db_find_sym_and_offset((db_addr_t)(intptr_t)c->c_func, &name,
		    &offset);
		name = name ? name : question;
		b = (bucket - cc->cc_wheel);
		if (b < 0)
			b = -WHEELSIZE;
		db_printf("%9d %2d/%-4d %16lx  %s\n",
		    c->c_time - cc->cc_ticks, b / WHEELSIZE, b,
		    (u_long)c->c_arg, name);
		if (CIRCQ_LAST(&c->c_list, bucket))
			break;
	}
}
Esempio n. 2
0
void
db_stack_trace_print(db_expr_t addr, bool have_addr,
		     db_expr_t count, const char *modif,
		     void (*pr)(const char *, ...))
{
	struct frame	*frame, *prevframe;
	db_addr_t	pc;
	bool		kernel_only = true;
	bool		trace_thread = false;
	bool		lwpaddr = false;
	const char	*cp = modif;
	char		c;

	if (ddb_cpuinfo == NULL)
		ddb_cpuinfo = curcpu();

	while ((c = *cp++) != 0) {
		if (c == 'a') {
			lwpaddr = true;
			trace_thread = true;
		}
		if (c == 't')
			trace_thread = true;
		if (c == 'u')
			kernel_only = false;
	}

	if (!have_addr) {
		frame = (struct frame *)DDB_TF->tf_out[6];
		pc = DDB_TF->tf_pc;
	} else {
		if (trace_thread) {
			struct proc *p;
			struct user *u;
			struct lwp *l;
			if (lwpaddr) {
				l = (struct lwp *)addr;
				p = l->l_proc;
				(*pr)("trace: pid %d ", p->p_pid);
			} else {
				(*pr)("trace: pid %d ", (int)addr);
				p = p_find(addr, PFIND_LOCKED);
				if (p == NULL) {
					(*pr)("not found\n");
					return;
				}
				l = LIST_FIRST(&p->p_lwps);
				KASSERT(l != NULL);
			}
			(*pr)("lid %d ", l->l_lid);
			if ((l->l_flag & LW_INMEM) == 0) {
				(*pr)("swapped out\n");
				return;
			}
			u = l->l_addr;
			frame = (struct frame *)u->u_pcb.pcb_sp;
			pc = u->u_pcb.pcb_pc;
			(*pr)("at %p\n", frame);
		} else {
			frame = (struct frame *)addr;
			pc = 0;
		}
	}

	while (count--) {
		int		i;
		db_expr_t	offset;
		const char	*name;
		db_addr_t	prevpc;

#define FR(framep,field) (INKERNEL(framep)			\
				? (u_int)(framep)->field	\
				: fuword(&(framep)->field))

		/* Fetch return address and arguments frame */
		prevpc = (db_addr_t)FR(frame, fr_pc);
		prevframe = (struct frame *)FR(frame, fr_fp);

		/*
		 * Switch to frame that contains arguments
		 */
		if (prevframe == NULL || (!INKERNEL(prevframe) && kernel_only))
			return;

		if ((ONINTSTACK(frame) && !ONINTSTACK(prevframe)) ||
		    (INKERNEL(frame) && !INKERNEL(prevframe))) {
			/* We're crossing a trap frame; pc = %l1 */
			prevpc = (db_addr_t)FR(frame, fr_local[1]);
		}

		name = NULL;
		if (INKERNEL(pc))
			db_find_sym_and_offset(pc, &name, &offset);
		if (name == NULL)
			(*pr)("0x%lx(", pc);
		else
			(*pr)("%s(", name);

		/*
		 * Print %i0..%i5, hope these still reflect the
		 * actual arguments somewhat...
		 */
		for (i = 0; i < 6; i++)
			(*pr)("0x%x%s", FR(frame, fr_arg[i]),
				(i < 5) ? ", " : ") at ");
		if (INKERNEL(prevpc))
			db_printsym(prevpc, DB_STGY_PROC, pr);
		else
			(*pr)("0x%lx", prevpc);
		(*pr)("\n");

		pc = prevpc;
		frame = prevframe;
	}
}
Esempio n. 3
0
void
db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count,
    const char *modif, void (*pr)(const char *, ...))
{
#ifndef DDB_TRACE
	struct pcb *pcb;
	struct proc *p;
	struct lwp *l;

	if (!have_addr) {
		stacktrace_subr(ddb_regs.f_regs[_R_A0],
				ddb_regs.f_regs[_R_A1],
				ddb_regs.f_regs[_R_A2],
				ddb_regs.f_regs[_R_A3],
				ddb_regs.f_regs[_R_PC],
				ddb_regs.f_regs[_R_SP],
				/* non-virtual frame pointer */
				ddb_regs.f_regs[_R_S8],
				ddb_regs.f_regs[_R_RA],
				pr);
		return;
	}

	/* "trace/t" */
	(*pr)("pid %d ", (int)addr);
	p = p_find(addr, PFIND_LOCKED);
	if (p == NULL) {
		(*pr)("not found\n");
		return;
	}	
	l = LIST_FIRST(&p->p_lwps); /* XXX NJWLWP */
	if (!(l->l_flag & LW_INMEM)) {
		(*pr)("swapped out\n");
		return;
	}

	pcb = &(l->l_addr->u_pcb);
	(*pr)("at %p\n", pcb);

	stacktrace_subr(0,0,0,0,	/* no args known */
			(int)cpu_switchto,
			pcb->pcb_context[8],
			pcb->pcb_context[9],
			pcb->pcb_context[10],
			pr);
#else
/*
 * Incomplete but practically useful stack backtrace.
 */
#define	MIPS_JR_RA	0x03e00008	/* instruction code for jr ra */
#define	MIPS_JR_K0	0x03400008	/* instruction code for jr k0 */
#define	MIPS_ERET	0x42000018	/* instruction code for eret */
	unsigned va, pc, ra, sp, func;
	int insn;
	InstFmt i;
	int stacksize;
	db_addr_t offset;
	const char *name;
	extern char verylocore[];

	pc = ddb_regs.f_regs[_R_PC];
	sp = ddb_regs.f_regs[_R_SP];
	ra = ddb_regs.f_regs[_R_RA];
	do {
		va = pc;
		do {
			va -= sizeof(int);
			insn = *(int *)va;
			if (insn == MIPS_ERET)
				goto mips3_eret;
		} while (insn != MIPS_JR_RA && insn != MIPS_JR_K0);
		va += sizeof(int);
	mips3_eret:
		va += sizeof(int);
		while (*(int *)va == 0x00000000)
			va += sizeof(int);
		func = va;
		stacksize = 0;
		do {
			i.word = *(int *)va;
			if (i.IType.op == OP_SW
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_RA)
				ra = *(int *)(sp + (short)i.IType.imm);
			if (i.IType.op == OP_ADDIU
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_SP)
				stacksize = -(short)i.IType.imm;
			va += sizeof(int);
		} while (va < pc);

		db_find_sym_and_offset(func, &name, &offset);
		if (name == 0)
			name = "?";
		(*pr)("%s()+0x%x, called by %p, stack size %d\n",
			name, pc - func, (void *)ra, stacksize);

		if (ra == pc) {
			(*pr)("-- loop? --\n");
			return;
		}
		sp += stacksize;
		pc = ra;
	} while (pc > (unsigned)verylocore);
	if (pc < 0x80000000)
		(*pr)("-- user process --\n");
	else
		(*pr)("-- kernel entry --\n");
#endif
}
Esempio n. 4
0
void
db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count,
    const char *modif, void (*pr)(const char *, ...))
{
#ifndef DDB_TRACE
	struct pcb *pcb;
	struct proc *p;
	struct lwp *l;
	const char *cp = modif;
	char c;
	bool lwpaddr = false;

	if (!have_addr) {
		struct reg * regs = &ddb_regs;
		stacktrace_subr(regs->r_regs[_R_A0],
				regs->r_regs[_R_A1],
				regs->r_regs[_R_A2],
				regs->r_regs[_R_A3],
				regs->r_regs[_R_PC],
				regs->r_regs[_R_SP],
				/* non-virtual frame pointer */
				regs->r_regs[_R_S8],
				regs->r_regs[_R_RA],
				pr);
		return;
	}

	while ((c = *cp++) != 0) {
		if (c == 'a') {
			lwpaddr = true;
		}
	}

	if (lwpaddr) {
		l = (struct lwp *)(intptr_t)addr;
		(*pr)("pid %d.%d ", l->l_proc->p_pid, l->l_lid);
	} else {
		/* "trace/t" */

		(*pr)("pid %d ", (int)addr);
		p = proc_find_raw(addr);
		if (p == NULL) {
			(*pr)("not found\n");
			return;
		}	
		l = LIST_FIRST(&p->p_lwps); /* XXX NJWLWP */
	}

	pcb = lwp_getpcb(l);
	(*pr)("at %p\n", pcb);

	stacktrace_subr(0,0,0,0,	/* no args known */
			(vaddr_t)cpu_switchto,
			pcb->pcb_context.val[_L_SP],
			pcb->pcb_context.val[_L_S8],
			pcb->pcb_context.val[_L_RA],
			pr);
#else
/*
 * Incomplete but practically useful stack backtrace.
 */
#define	MIPS_JR_RA	0x03e00008	/* instruction code for jr ra */
#define	MIPS_JR_K0	0x03400008	/* instruction code for jr k0 */
#define	MIPS_ERET	0x42000018	/* instruction code for eret */
	register_t va, pc, ra, sp, func;
	int insn;
	InstFmt i;
	int stacksize;
	db_addr_t offset;
	const char *name;
	extern char verylocore[];

	pc = ddb_regs.r_regs[_R_PC];
	sp = ddb_regs.r_regs[_R_SP];
	ra = ddb_regs.r_regs[_R_RA];
	do {
		va = pc;
		do {
			va -= sizeof(int);
			insn = *(int *)(intptr_t)va;
			if (insn == MIPS_ERET)
				goto mips3_eret;
		} while (insn != MIPS_JR_RA && insn != MIPS_JR_K0);
		va += sizeof(int);
	mips3_eret:
		va += sizeof(int);
		while (*(int *)(intptr_t)va == 0x00000000)
			va += sizeof(int);
		func = va;
		stacksize = 0;
		do {
			i.word = *(int *)(intptr_t)va;
			if (((i.IType.op == OP_SW) || (i.IType.op == OP_SD))
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_RA)
				ra = *(int *)(intptr_t)(sp + (short)i.IType.imm);
			if (((i.IType.op == OP_ADDIU) || (i.IType.op == OP_DADDIU))
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_SP)
				stacksize = -(short)i.IType.imm;
			va += sizeof(int);
		} while (va < pc);

		db_find_sym_and_offset(func, &name, &offset);
		if (name == 0)
			name = "?";
		(*pr)("%s()+0x%x, called by %p, stack size %d\n",
			name, pc - func, (void *)(intptr_t)ra, stacksize);

		if (ra == pc) {
			(*pr)("-- loop? --\n");
			return;
		}
		sp += stacksize;
		pc = ra;
	} while (pc > (intptr_t)verylocore);
	if (pc < 0x80000000)
		(*pr)("-- user process --\n");
	else
		(*pr)("-- kernel entry --\n");
#endif
}